├── AUTHORS ├── AUTHORS_BAP ├── COPYING ├── COPYING_BAP ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── README.md ├── VEX ├── HACKING.README ├── LICENSE.GPL ├── LICENSE.README ├── Makefile ├── OPENREIL.README ├── TODO.txt ├── auxprogs │ └── genoffsets.c ├── nanoarm.orig ├── orig_amd64 │ ├── Compare.hs │ ├── SortedToOrig.hs │ ├── test1.orig │ ├── test1.sorted │ ├── test2.orig │ └── test2.sorted ├── orig_arm │ ├── nanoarm │ └── nanoarm.orig ├── orig_ppc32 │ ├── date.orig │ ├── loadsafp.orig │ ├── morefp.orig │ └── return0.orig ├── orig_x86 │ ├── exit42.orig │ ├── fpu_mmx_sse.orig │ └── manyfp.orig ├── priv │ ├── guest_amd64_defs.h │ ├── guest_amd64_helpers.c │ ├── guest_amd64_toIR.c │ ├── guest_arm64_defs.h │ ├── guest_arm64_helpers.c │ ├── guest_arm64_toIR.c │ ├── guest_arm_defs.h │ ├── guest_arm_helpers.c │ ├── guest_arm_toIR.c │ ├── guest_generic_bb_to_IR.c │ ├── guest_generic_bb_to_IR.h │ ├── guest_generic_x87.c │ ├── guest_generic_x87.h │ ├── guest_mips_defs.h │ ├── guest_mips_helpers.c │ ├── guest_mips_toIR.c │ ├── guest_ppc_defs.h │ ├── guest_ppc_helpers.c │ ├── guest_ppc_toIR.c │ ├── guest_s390_defs.h │ ├── guest_s390_helpers.c │ ├── guest_s390_toIR.c │ ├── guest_x86_defs.h │ ├── guest_x86_helpers.c │ ├── guest_x86_toIR.c │ ├── host_amd64_defs.c │ ├── host_amd64_defs.h │ ├── host_amd64_isel.c │ ├── host_arm64_defs.c │ ├── host_arm64_defs.h │ ├── host_arm64_isel.c │ ├── host_arm_defs.c │ ├── host_arm_defs.h │ ├── host_arm_isel.c │ ├── host_generic_maddf.c │ ├── host_generic_maddf.h │ ├── host_generic_reg_alloc2.c │ ├── host_generic_regs.c │ ├── host_generic_regs.h │ ├── host_generic_simd128.c │ ├── host_generic_simd128.h │ ├── host_generic_simd256.c │ ├── host_generic_simd256.h │ ├── host_generic_simd64.c │ ├── host_generic_simd64.h │ ├── host_mips_defs.c │ ├── host_mips_defs.h │ ├── host_mips_isel.c │ ├── host_ppc_defs.c │ ├── host_ppc_defs.h │ ├── host_ppc_isel.c │ ├── host_s390_defs.c │ ├── host_s390_defs.h │ ├── host_s390_isel.c │ ├── host_x86_defs.c │ ├── host_x86_defs.h │ ├── host_x86_isel.c │ ├── ir_defs.c │ ├── ir_inject.c │ ├── ir_match.c │ ├── ir_match.h │ ├── ir_opt.c │ ├── ir_opt.h │ ├── main_globals.c │ ├── main_globals.h │ ├── main_main.c │ ├── main_util.c │ ├── main_util.h │ ├── s390_defs.h │ ├── s390_disasm.c │ └── s390_disasm.h ├── pub │ ├── libvex.h │ ├── libvex_basictypes.h │ ├── libvex_emnote.h │ ├── libvex_guest_amd64.h │ ├── libvex_guest_arm.h │ ├── libvex_guest_arm64.h │ ├── libvex_guest_mips32.h │ ├── libvex_guest_mips64.h │ ├── libvex_guest_ppc32.h │ ├── libvex_guest_ppc64.h │ ├── libvex_guest_s390x.h │ ├── libvex_guest_x86.h │ ├── libvex_ir.h │ ├── libvex_s390x_common.h │ └── libvex_trc_values.h ├── switchback │ ├── Makefile │ ├── binary_switchback.pl │ ├── linker.c │ ├── linker.h │ ├── switchback.c │ ├── test_bzip2.c │ ├── test_emfloat.c │ ├── test_hello.c │ ├── test_ppc_jm1.c │ └── test_simple.c ├── test │ ├── fldenv.c │ ├── fp1.c │ ├── fp1.s │ ├── fpconst.c │ ├── fpgames.s │ ├── fpspeed.c │ ├── fpucw.c │ ├── frstor.c │ ├── fsave.c │ ├── fstenv.c │ ├── fxsave.c │ ├── mmxtest.c │ ├── mxcsr.c │ ├── rounderr.c │ ├── test-amd64-muldiv.h │ ├── test-amd64-shift.h │ ├── test-amd64.c │ ├── test-amd64.h │ ├── test-i386-muldiv.h │ ├── test-i386-shift.h │ ├── test-i386.c │ ├── test-i386.h │ ├── x87fxam.c │ └── x87tst.c ├── unused │ ├── arena.h │ ├── dispatch.c │ └── linker.c └── useful │ ├── Makefile-vex │ ├── cpuid.c │ ├── fp_80_64.c │ ├── fpround.c │ ├── fspill.c │ ├── gradual_underflow.c │ ├── hd_fpu.c │ ├── show_fp_state.c │ ├── smchash.c │ ├── test_main.c │ ├── test_main.h │ ├── test_main.h.base │ └── x87_to_vex_and_back.c ├── autogen.sh ├── capstone ├── Makefile └── config.mk ├── configure.ac ├── docs └── README.html ├── gpl-2.0.txt ├── libasmir ├── Doxyfile ├── Makefile.am ├── include │ ├── common.h │ ├── disasm.h │ ├── exp.h │ ├── info.h │ ├── irtoir-i386.h │ ├── irtoir-internal.h │ ├── irtoir.h │ ├── irvisitor.h │ ├── jumpbuf.h │ ├── stmt.h │ └── vexmem.h └── src │ ├── Makefile.am │ ├── common.cpp │ ├── disasm-capstone.cpp │ ├── exp.cpp │ ├── irtoir-arm.cpp │ ├── irtoir-i386.cpp │ ├── irtoir.cpp │ ├── stmt.cpp │ ├── vexir.c │ └── vexmem.c ├── libopenreil ├── Makefile.am ├── apps │ ├── Makefile.am │ └── translate-inst.cpp ├── include │ ├── libopenreil.h │ ├── reil_ir.h │ └── reil_translator.h └── src │ ├── Makefile.am │ ├── libopenreil.cpp │ ├── makelib.sh │ └── reil_translator.cpp ├── pyopenreil ├── IR.py ├── Makefile.am ├── REIL.py ├── VM.py ├── __init__.py ├── arch │ ├── __init__.py │ ├── arm.py │ └── x86.py ├── scripts │ ├── gdb_reiltrans.py │ ├── ida_translate_func.py │ └── kd_reiltrans.py ├── src │ ├── Makefile │ ├── libopenreil.pxd │ └── translator.pyx ├── symbolic.py └── utils │ ├── GDB.py │ ├── IDA.py │ ├── __init__.py │ ├── asm.py │ ├── bin_BFD.py │ ├── bin_PE.py │ ├── kd.py │ └── mongodb.py └── tests ├── fib.c ├── fib_arm.elf ├── fib_x86.elf ├── fib_x86.pe ├── md5.c ├── md5_arm.elf ├── md5_x86.elf ├── md5_x86.pe ├── rc4.c ├── rc4_arm.elf ├── rc4_x86.elf ├── rc4_x86.pe ├── run_unittest.py ├── test_fib.py ├── test_kao.py ├── test_md5.py ├── test_rc4.py └── toyproject.exe /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | OpenREIL was developed by Dmytro Oleksiuk (aka Cr4sh) 3 | 4 | cr4sh0@gmail.com | http://blog.cr4.sh | @d_olex 5 | -------------------------------------------------------------------------------- /AUTHORS_BAP: -------------------------------------------------------------------------------- 1 | The following people currently work on BAP: 2 | 3 | David Brumley 4 | Thanassis Avgerinos 5 | Edward J. Schwartz 6 | 7 | Previous developers include: 8 | 9 | Ivan Jager 10 | JongHyup Lee 11 | Spencer Whitman 12 | 13 | The original version of BAP was called VINE. VINE developers included: 14 | 15 | David Brumley 16 | Juan Caballero 17 | Cody Hartwig 18 | Ivan Jager 19 | Eric Li 20 | James Newsome 21 | Pongsin Poosankam 22 | Heng Yin 23 | 24 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2015, Dmytro Oleksiuk. 3 | 4 | See COPYING_BAP and AUTHORS_BAP for more information. 5 | 6 | -------------------------------------------------------------------------------- /COPYING_BAP: -------------------------------------------------------------------------------- 1 | Copyright © 2009 Carnegie-Mellon University, David Brumley, and Ivan Jager. 2 | 3 | This library is made available under a dual licensing scheme. 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or (at 8 | your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 18 | USA 19 | 20 | Linking BAP statically or dynamically with other modules is making a 21 | combined work based on BAP. Thus, the terms and conditions of the GNU 22 | General Public License cover the whole combination. 23 | 24 | 25 | For any other uses of BAP, you must first obtain a commercial 26 | license. Please contact dbrumley@cs.cmu.edu for information about 27 | commercial licensing. 28 | 29 | 30 | See the respective licenses of included projects for additional 31 | copyright information. 32 | 33 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/ChangeLog -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | Please refer to docs/README.html for more detailed information. 3 | 4 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | BAPDIRS = libasmir libopenreil pyopenreil 2 | SUBDIRS = VEX capstone $(BAPDIRS) 3 | 4 | .PHONY: cscope 5 | cscope: 6 | 7 | cscope -b `find . -name "*.[ch]" -or -name "*.hh" -or -name "*.cc" -or -name "*.cpp"` 8 | 9 | .PHONY: bap-clean 10 | bap-clean: 11 | 12 | for d in $(BAPDIRS); do $(MAKE) -C $$d clean; done 13 | 14 | .PHONY: test 15 | test: 16 | 17 | python tests/run_unittest.py 18 | 19 | .PHONY: doc 20 | doc: 21 | 22 | grip --export && mv README.html docs/README.html 23 | 24 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | OpenREIL is open source library that implements translator and tools for REIL (Reverse Engineering Intermediate Language). 3 | 4 | Please refer to docs/README.html for more detailed information. 5 | 6 | 7 | Developed by Dmytro Oleksiuk (aka Cr4sh), cr4sh0@gmail.com 8 | -------------------------------------------------------------------------------- /VEX/HACKING.README: -------------------------------------------------------------------------------- 1 | 2 | This directory and its children contain LibVEX, a library for dynamic 3 | binary instrumentation and translation. See LICENSE.README for 4 | licensing and contribution information. 5 | 6 | -------------------------------------------------------------------------------- /VEX/LICENSE.README: -------------------------------------------------------------------------------- 1 | 2 | This directory and its children contain LibVEX, a library for dynamic 3 | binary instrumentation and translation. 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License as 7 | published by the Free Software Foundation; either version 2 of the 8 | License, or (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 | 02110-1301, USA. 19 | 20 | The GNU General Public License is contained in the file LICENSE.GPL. 21 | 22 | If you want to contribute code to LibVEX, please ensure it is licensed 23 | as "GPL v2 or later". 24 | -------------------------------------------------------------------------------- /VEX/OPENREIL.README: -------------------------------------------------------------------------------- 1 | This is libVEX from Vagrind, version from 29 Mar 2015 with minor patches applied. 2 | Visit http://valgrind.org for more information. 3 | 4 | Revision info 5 | ================== 6 | URL: svn://svn.valgrind.org/vex/trunk 7 | Repository Root: svn://svn.valgrind.org/vex 8 | Repository UUID: 8f6e269a-dfd6-0310-a8e1-e2731360e62c 9 | Revision: 3109 10 | 11 | -------------------------------------------------------------------------------- /VEX/TODO.txt: -------------------------------------------------------------------------------- 1 | 2 | Last updated 15 Nov 04 3 | ~~~~~~~~~~~~~~~~~~~~~~ 4 | 5 | Critical (correctness) 6 | ~~~~~~~~~~~~~~~~~~~~~~ 7 | x86 isel: should free up all fp reg tags when calling a helper. 8 | And save FP and SSE insns across the helper. 9 | 10 | iropt: reconsider precise exceptions 11 | 12 | x86 guest: look at FP accuracy 13 | 14 | 15 | Optimisation opportunities 16 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 17 | Improved isel for memcheck artefacts on x86 (generate neg ; sbbl) 18 | 19 | Assess tt_fast miss rates 20 | 21 | improve stack-update pass 22 | 23 | proper profiling machinery 24 | 25 | do not CSE exprs :: Ity_Bit 26 | 27 | x86 iselIntExpr_RMI: actually generate the M case if possible 28 | 29 | 30 | JIT speedups 31 | ~~~~~~~~~~~~ 32 | Ensure incremental flatness throughout 33 | 34 | Profile again with cachegrind/calltree 35 | 36 | change IRTemp to 16 bits? 37 | 38 | 39 | Integration 40 | ~~~~~~~~~~~ 41 | Get rid of sloppy-malloc 42 | 43 | Get rid of partial-loads-ok 44 | 45 | Optimisation after first instrumentation rather than 2nd ? 46 | 47 | disallow dirty helpers from writing SP/IP 48 | 49 | write API doc, clarify IR semantics 50 | 51 | make IR utils module 52 | 53 | generic stack pointer identification at startup? 54 | 55 | New memstack_k: old or new sp? 56 | -------------------------------------------------------------------------------- /VEX/nanoarm.orig: -------------------------------------------------------------------------------- 1 | 0: e1a0c00d mov ip, sp 2 | . 0 00008000 4 3 | . 0d c0 a0 e1 4 | 5 | 4: e92dd810 stmdb sp!, {r4, fp, ip, lr, pc} 6 | . 1 00008004 4 7 | . 10 d8 2d e9 8 | 9 | 8: e24cb004 sub fp, ip, #4 ; 0x4 10 | . 2 00008008 4 11 | . 04 b0 4c e2 12 | 13 | c: e3a00014 mov r0, #20 ; 0x14 14 | . 3 0000800C 4 15 | . 14 00 a0 e3 16 | 17 | 10: ebfffffe bl 0 18 | . 4 00008010 4 19 | . fe ff ff eb 20 | -------------------------------------------------------------------------------- /VEX/orig_amd64/Compare.hs: -------------------------------------------------------------------------------- 1 | 2 | module Main where 3 | 4 | import Char ( isSpace ) 5 | 6 | {- Compares a .sorted file with a raw printout of instructions 7 | and shows differences. 8 | 9 | First file (REF) is has lines of format 10 | 11 | hex-digits SPACEs insn(possibly with spaces) 12 | 13 | Second file (TEST) has lines of format 14 | 15 | insn(possibly with spaces) 16 | 17 | Purpose is to extract the insn (text), remove spaces, and compare. 18 | 19 | How to use: 20 | (cd .. && make) && (../vex test1.orig | grep LALALA | cut -b 22- > out.txt) 21 | /home/sewardj/Tools/HugsInst/bin/runhugs Compare.hs | grep FAIL 22 | -} 23 | 24 | main = mayn "test2.sorted" "out.txt" 25 | 26 | mayn :: String -> String -> IO () 27 | 28 | mayn sorted_fn dump_fn 29 | = do sorted <- readFile sorted_fn 30 | dump <- readFile dump_fn 31 | let ress = zipWith check (lines (deTab sorted)) 32 | (lines (deTab dump)) 33 | putStrLn (unlines ress) 34 | 35 | 36 | check :: String -> String -> String 37 | check ref test 38 | = let ref_clean = dropWhile isHex ref 39 | ok = compere ref_clean test 40 | summary = grok ("REF: " ++ trim ref_clean) 41 | ++ " " ++ grok ("TEST: " ++ trim test) 42 | in 43 | if ok 44 | then "pass: " ++ summary 45 | else "FAIL: " ++ summary 46 | 47 | trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace 48 | 49 | compere s1 s2 = filter (not . isSpace) s1 == filter (not . isSpace) s2 50 | 51 | isHex c = c `elem` "ABCDEF0123456789abcdef" 52 | 53 | grok str 54 | = let n = length str 55 | limit = 40 56 | in 57 | if n >= limit 58 | then str 59 | else take limit (str ++ repeat ' ') 60 | 61 | deTab [] = [] 62 | deTab (c:cs) = if c == '\t' then " " ++ deTab cs 63 | else c: deTab cs 64 | -------------------------------------------------------------------------------- /VEX/orig_amd64/SortedToOrig.hs: -------------------------------------------------------------------------------- 1 | 2 | module Main where 3 | 4 | main 5 | = do x1 <- readFile "test2.sorted" 6 | let x2 = lines x1 7 | x3 = zip [1 ..] x2 8 | x4 = concat (map qq x3) 9 | --putStr x4 10 | writeFile "test2.orig" x4 11 | 12 | 13 | qq :: (Int, String) -> String 14 | qq (n, s0) 15 | = let ws = words s0 16 | bytes = head ws 17 | rest = unwords (tail ws) 18 | bytes2 = foo bytes 19 | in 20 | unlines [ 21 | "", 22 | rest, 23 | ". " ++ show n ++ " 0x12345678 " ++ show (1 + (length bytes `div` 2)), 24 | ". " ++ bytes2 ++ "C3" 25 | ] 26 | 27 | 28 | foo [] = [] 29 | foo (x:y:rest) = x:y:' ':foo rest 30 | -------------------------------------------------------------------------------- /VEX/orig_arm/nanoarm: -------------------------------------------------------------------------------- 1 | 0: e1a0c00d mov ip, sp 2 | 4: e92dd810 stmdb sp!, {r4, fp, ip, lr, pc} 3 | 8: e24cb004 sub fp, ip, #5 ; 0x4 4 | c: e3a00014 mov r0, #20 ; 0x14 5 | 10: ebfffffe bl 0 6 | . 0 00008000 20 7 | . 0d c0 a0 e1 10 d8 2d e9 05 b0 4c e2 14 00 a0 e3 fe ff ff eb 8 | -------------------------------------------------------------------------------- /VEX/orig_arm/nanoarm.orig: -------------------------------------------------------------------------------- 1 | 0: e1a0c00d mov ip, sp 2 | . 0 00008000 4 3 | . 0d c0 a0 e1 4 | 5 | 4: e92dd810 stmdb sp!, {r4, fp, ip, lr, pc} 6 | . 1 00008004 4 7 | . 10 d8 2d e9 8 | 9 | 8: e24cb004 sub fp, ip, #4 ; 0x4 10 | . 2 00008008 4 11 | . 04 b0 4c e2 12 | 13 | c: e3a00014 mov r0, #20 ; 0x14 14 | . 3 0000800C 4 15 | . 14 00 a0 e3 16 | 17 | 10: ebfffffe bl 0 18 | . 4 00008010 4 19 | . fe ff ff eb 20 | -------------------------------------------------------------------------------- /VEX/priv/guest_generic_x87.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin guest_generic_x87.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | /* This file contains functions for doing some x87-specific 37 | operations. Both the amd64 and x86 front ends (guests) indirectly 38 | call these functions via guest helper calls. By putting them here, 39 | code duplication is avoided. Some of these functions are tricky 40 | and hard to verify, so there is much to be said for only having one 41 | copy thereof. 42 | */ 43 | 44 | #ifndef __VEX_GUEST_GENERIC_X87_H 45 | #define __VEX_GUEST_GENERIC_X87_H 46 | 47 | #include "libvex_basictypes.h" 48 | 49 | 50 | /* Convert an IEEE754 double (64-bit) into an x87 extended double 51 | (80-bit), mimicing the hardware fairly closely. Both numbers are 52 | stored little-endian. Limitations, all of which could be fixed, 53 | given some level of hassle: 54 | 55 | * Identity of NaNs is not preserved. 56 | 57 | See comments in the code for more details. 58 | */ 59 | extern 60 | void convert_f64le_to_f80le ( /*IN*/UChar* f64, /*OUT*/UChar* f80 ); 61 | 62 | 63 | /* Convert an x87 extended double (80-bit) into an IEEE 754 double 64 | (64-bit), mimicking the hardware fairly closely. Both numbers are 65 | stored little-endian. Limitations, both of which could be fixed, 66 | given some level of hassle: 67 | 68 | * Rounding following truncation could be a bit better. 69 | 70 | * Identity of NaNs is not preserved. 71 | 72 | See comments in the code for more details. 73 | */ 74 | extern 75 | void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 ); 76 | 77 | 78 | /* Layout of the real x87 state. */ 79 | typedef 80 | struct { 81 | UShort env[14]; 82 | UChar reg[80]; 83 | } 84 | Fpu_State; 85 | 86 | /* Offsets, in 16-bit ints, into the FPU environment (env) area. */ 87 | #define FP_ENV_CTRL 0 88 | #define FP_ENV_STAT 2 89 | #define FP_ENV_TAG 4 90 | #define FP_ENV_IP 6 /* and 7 */ 91 | #define FP_ENV_CS 8 92 | #define FP_ENV_LSTOP 9 93 | #define FP_ENV_OPOFF 10 /* and 11 */ 94 | #define FP_ENV_OPSEL 12 95 | #define FP_REG(ii) (10*(7-(ii))) 96 | 97 | 98 | /* Layout of the 16-bit FNSAVE x87 state. */ 99 | typedef 100 | struct { 101 | UShort env[7]; 102 | UChar reg[80]; 103 | } 104 | Fpu_State_16; 105 | 106 | /* Offsets, in 16-bit ints, into the FPU environment (env) area. */ 107 | #define FPS_ENV_CTRL 0 108 | #define FPS_ENV_STAT 1 109 | #define FPS_ENV_TAG 2 110 | #define FPS_ENV_IP 3 111 | #define FPS_ENV_CS 4 112 | #define FPS_ENV_OPOFF 5 113 | #define FPS_ENV_OPSEL 6 114 | 115 | 116 | /* Do the computations for x86/amd64 FXTRACT. Called directly from 117 | generated code. CLEAN HELPER. */ 118 | extern ULong x86amd64g_calculate_FXTRACT ( ULong arg, HWord getExp ); 119 | 120 | /* Compute result and new OSZACP flags for all 8-bit PCMP{E,I}STR{I,M} 121 | variants. See bigger comment on implementation of this function 122 | for details on call/return conventions. */ 123 | extern Bool compute_PCMPxSTRx ( /*OUT*/V128* resV, 124 | /*OUT*/UInt* resOSZACP, 125 | V128* argLV, V128* argRV, 126 | UInt zmaskL, UInt zmaskR, 127 | UInt imm8, Bool isxSTRM ); 128 | 129 | /* Compute result and new OSZACP flags for all 16-bit PCMP{E,I}STR{I,M} 130 | variants. See bigger comment on implementation of this function 131 | for details on call/return conventions. */ 132 | extern Bool compute_PCMPxSTRx_wide ( /*OUT*/V128* resV, 133 | /*OUT*/UInt* resOSZACP, 134 | V128* argLV, V128* argRV, 135 | UInt zmaskL, UInt zmaskR, 136 | UInt imm8, Bool isxSTRM ); 137 | 138 | #endif /* ndef __VEX_GUEST_GENERIC_X87_H */ 139 | 140 | /*---------------------------------------------------------------*/ 141 | /*--- end guest_generic_x87.h ---*/ 142 | /*---------------------------------------------------------------*/ 143 | -------------------------------------------------------------------------------- /VEX/priv/host_generic_maddf.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin host_generic_maddf.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | Compute x * y + z as ternary operation. 8 | Copyright (C) 2010-2013 Free Software Foundation, Inc. 9 | This file is part of the GNU C Library. 10 | Contributed by Jakub Jelinek , 2010. 11 | 12 | The GNU C Library is free software; you can redistribute it and/or 13 | modify it under the terms of the GNU Lesser General Public 14 | License as published by the Free Software Foundation; either 15 | version 2.1 of the License, or (at your option) any later version. 16 | 17 | The GNU C Library is distributed in the hope that it will be useful, 18 | but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | Lesser General Public License for more details. 21 | 22 | You should have received a copy of the GNU Lesser General Public 23 | License along with the GNU C Library; if not, see 24 | . 25 | */ 26 | 27 | /* Generic helper functions for doing FMA, i.e. compute x * y + z 28 | as ternary operation. 29 | These are purely back-end entities and cannot be seen/referenced 30 | from IR. */ 31 | 32 | #ifndef __VEX_HOST_GENERIC_MADDF_H 33 | #define __VEX_HOST_GENERIC_MADDF_H 34 | 35 | #include "libvex_basictypes.h" 36 | 37 | extern VEX_REGPARM(3) 38 | void h_generic_calc_MAddF32 ( /*OUT*/Float*, Float*, Float*, Float* ); 39 | 40 | extern VEX_REGPARM(3) 41 | void h_generic_calc_MAddF64 ( /*OUT*/Double*, Double*, Double*, 42 | Double* ); 43 | 44 | #endif /* ndef __VEX_HOST_GENERIC_MADDF_H */ 45 | 46 | /*---------------------------------------------------------------*/ 47 | /*--- end host_generic_maddf.h --*/ 48 | /*---------------------------------------------------------------*/ 49 | -------------------------------------------------------------------------------- /VEX/priv/host_generic_simd128.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin host_generic_simd128.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2010-2013 OpenWorks GbR 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | /* Generic helper functions for doing 128-bit SIMD arithmetic in cases 32 | where the instruction selectors cannot generate code in-line. 33 | These are purely back-end entities and cannot be seen/referenced 34 | as clean helper functions from IR. 35 | 36 | These will get called from generated code and therefore should be 37 | well behaved -- no floating point or mmx insns, just straight 38 | integer code. 39 | 40 | Each function implements the correspondingly-named IR primop. 41 | */ 42 | 43 | #ifndef __VEX_HOST_GENERIC_SIMD128_H 44 | #define __VEX_HOST_GENERIC_SIMD128_H 45 | 46 | #include "libvex_basictypes.h" 47 | 48 | extern VEX_REGPARM(3) 49 | void h_generic_calc_Mul32x4 ( /*OUT*/V128*, V128*, V128* ); 50 | extern VEX_REGPARM(3) 51 | void h_generic_calc_Max32Sx4 ( /*OUT*/V128*, V128*, V128* ); 52 | extern VEX_REGPARM(3) 53 | void h_generic_calc_Min32Sx4 ( /*OUT*/V128*, V128*, V128* ); 54 | extern VEX_REGPARM(3) 55 | void h_generic_calc_Max32Ux4 ( /*OUT*/V128*, V128*, V128* ); 56 | extern VEX_REGPARM(3) 57 | void h_generic_calc_Min32Ux4 ( /*OUT*/V128*, V128*, V128* ); 58 | extern VEX_REGPARM(3) 59 | void h_generic_calc_Max16Ux8 ( /*OUT*/V128*, V128*, V128* ); 60 | extern VEX_REGPARM(3) 61 | void h_generic_calc_Min16Ux8 ( /*OUT*/V128*, V128*, V128* ); 62 | extern VEX_REGPARM(3) 63 | void h_generic_calc_Max8Sx16 ( /*OUT*/V128*, V128*, V128* ); 64 | extern VEX_REGPARM(3) 65 | void h_generic_calc_Min8Sx16 ( /*OUT*/V128*, V128*, V128* ); 66 | extern VEX_REGPARM(3) 67 | void h_generic_calc_CmpEQ64x2 ( /*OUT*/V128*, V128*, V128* ); 68 | extern VEX_REGPARM(3) 69 | void h_generic_calc_CmpGT64Sx2 ( /*OUT*/V128*, V128*, V128* ); 70 | 71 | extern /*not-regparm*/ 72 | void h_generic_calc_SarN64x2 ( /*OUT*/V128*, V128*, UInt ); 73 | extern /*not-regparm*/ 74 | void h_generic_calc_SarN8x16 ( /*OUT*/V128*, V128*, UInt ); 75 | 76 | extern VEX_REGPARM(3) 77 | void h_generic_calc_QNarrowBin32Sto16Ux8 78 | ( /*OUT*/V128*, V128*, V128* ); 79 | extern VEX_REGPARM(3) 80 | void h_generic_calc_NarrowBin16to8x16 81 | ( /*OUT*/V128*, V128*, V128* ); 82 | extern VEX_REGPARM(3) 83 | void h_generic_calc_NarrowBin32to16x8 84 | ( /*OUT*/V128*, V128*, V128* ); 85 | 86 | extern VEX_REGPARM(3) 87 | void h_generic_calc_Perm32x4 ( /*OUT*/V128*, V128*, V128* ); 88 | 89 | extern /*not-regparm*/ 90 | UInt h_generic_calc_GetMSBs8x16 ( ULong w64hi, ULong w64lo ); 91 | 92 | #endif /* ndef __VEX_HOST_GENERIC_SIMD128_H */ 93 | 94 | /*---------------------------------------------------------------*/ 95 | /*--- end host_generic_simd128.h ---*/ 96 | /*---------------------------------------------------------------*/ 97 | -------------------------------------------------------------------------------- /VEX/priv/host_generic_simd256.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin host_generic_simd256.c ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2012-2013 OpenWorks GbR 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | /* Generic helper functions for doing 256-bit SIMD arithmetic in cases 32 | where the instruction selectors cannot generate code in-line. 33 | These are purely back-end entities and cannot be seen/referenced 34 | from IR. */ 35 | 36 | #include "libvex_basictypes.h" 37 | #include "host_generic_simd256.h" 38 | 39 | 40 | void VEX_REGPARM(3) 41 | h_generic_calc_Perm32x8 ( /*OUT*/V256* res, 42 | V256* argL, V256* argR ) 43 | { 44 | res->w32[0] = argL->w32[ argR->w32[0] & 7 ]; 45 | res->w32[1] = argL->w32[ argR->w32[1] & 7 ]; 46 | res->w32[2] = argL->w32[ argR->w32[2] & 7 ]; 47 | res->w32[3] = argL->w32[ argR->w32[3] & 7 ]; 48 | res->w32[4] = argL->w32[ argR->w32[4] & 7 ]; 49 | res->w32[5] = argL->w32[ argR->w32[5] & 7 ]; 50 | res->w32[6] = argL->w32[ argR->w32[6] & 7 ]; 51 | res->w32[7] = argL->w32[ argR->w32[7] & 7 ]; 52 | } 53 | 54 | 55 | /*---------------------------------------------------------------*/ 56 | /*--- end host_generic_simd256.c ---*/ 57 | /*---------------------------------------------------------------*/ 58 | -------------------------------------------------------------------------------- /VEX/priv/host_generic_simd256.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin host_generic_simd256.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2012-2013 OpenWorks GbR 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | /* Generic helper functions for doing 256-bit SIMD arithmetic in cases 32 | where the instruction selectors cannot generate code in-line. 33 | These are purely back-end entities and cannot be seen/referenced 34 | as clean helper functions from IR. 35 | 36 | These will get called from generated code and therefore should be 37 | well behaved -- no floating point or mmx insns, just straight 38 | integer code. 39 | 40 | Each function implements the correspondingly-named IR primop. 41 | */ 42 | 43 | #ifndef __VEX_HOST_GENERIC_SIMD256_H 44 | #define __VEX_HOST_GENERIC_SIMD256_H 45 | 46 | #include "libvex_basictypes.h" 47 | 48 | extern VEX_REGPARM(3) 49 | void h_generic_calc_Perm32x8 ( /*OUT*/V256*, V256*, V256* ); 50 | 51 | #endif /* ndef __VEX_HOST_GENERIC_SIMD256_H */ 52 | 53 | /*---------------------------------------------------------------*/ 54 | /*--- end host_generic_simd256.h ---*/ 55 | /*---------------------------------------------------------------*/ 56 | -------------------------------------------------------------------------------- /VEX/priv/ir_match.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin ir_match.c ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | /* Provides a facility for doing IR tree matching. */ 37 | 38 | #include "main_util.h" 39 | #include "ir_match.h" 40 | 41 | 42 | /* Assign a value to a binder. Checks for obvious stupidities. */ 43 | 44 | static 45 | void setBindee ( MatchInfo* mi, Int n, IRExpr* bindee ) 46 | { 47 | if (n < 0 || n >= N_IRMATCH_BINDERS) 48 | vpanic("setBindee: out of range index"); 49 | if (mi->bindee[n] != NULL) 50 | vpanic("setBindee: bindee already set"); 51 | mi->bindee[n] = bindee; 52 | } 53 | 54 | 55 | /* This is the actual matching function, recursing over the pattern 56 | and expression trees in the obvious way, and dumping any matches 57 | found into 'mi'. */ 58 | 59 | static 60 | Bool matchWrk ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) 61 | { 62 | switch (p->tag) { 63 | case Iex_Binder: /* aha, what we were looking for. */ 64 | setBindee(mi, p->Iex.Binder.binder, e); 65 | return True; 66 | case Iex_Unop: 67 | if (e->tag != Iex_Unop) return False; 68 | if (p->Iex.Unop.op != e->Iex.Unop.op) return False; 69 | if (!matchWrk(mi, p->Iex.Unop.arg, e->Iex.Unop.arg)) 70 | return False; 71 | return True; 72 | case Iex_Binop: 73 | if (e->tag != Iex_Binop) return False; 74 | if (p->Iex.Binop.op != e->Iex.Binop.op) return False; 75 | if (!matchWrk(mi, p->Iex.Binop.arg1, e->Iex.Binop.arg1)) 76 | return False; 77 | if (!matchWrk(mi, p->Iex.Binop.arg2, e->Iex.Binop.arg2)) 78 | return False; 79 | return True; 80 | case Iex_Load: 81 | if (e->tag != Iex_Load) return False; 82 | if (p->Iex.Load.end != e->Iex.Load.end) return False; 83 | if (p->Iex.Load.ty != e->Iex.Load.ty) return False; 84 | if (!matchWrk(mi, p->Iex.Load.addr, e->Iex.Load.addr)) 85 | return False; 86 | return True; 87 | case Iex_Const: 88 | if (e->tag != Iex_Const) return False; 89 | return eqIRConst(p->Iex.Const.con, e->Iex.Const.con); 90 | default: 91 | ppIRExpr(p); 92 | vpanic("match"); 93 | } 94 | } 95 | 96 | 97 | /* Top level entry point to the matcher. */ 98 | 99 | Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ) 100 | { 101 | Int i; 102 | for (i = 0; i < N_IRMATCH_BINDERS; i++) 103 | mi->bindee[i] = NULL; 104 | return matchWrk(mi, p, e); 105 | } 106 | 107 | 108 | 109 | /*---------------------------------------------------------------*/ 110 | /*--- end ir_match.c ---*/ 111 | /*---------------------------------------------------------------*/ 112 | -------------------------------------------------------------------------------- /VEX/priv/ir_match.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin ir_match.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | /* Provides a facility for doing IR tree matching. */ 37 | 38 | #ifndef __VEX_IR_MATCH_H 39 | #define __VEX_IR_MATCH_H 40 | 41 | #include "libvex_basictypes.h" 42 | #include "libvex_ir.h" 43 | #include "main_util.h" // NULL 44 | 45 | /* Patterns are simply IRExpr* trees, with IRExpr_Binder nodes at the 46 | leaves, indicating binding points. Use these magic macros to 47 | declare and define patterns. */ 48 | 49 | #define DECLARE_PATTERN(_patt) \ 50 | static IRExpr* _patt = NULL 51 | 52 | #define DEFINE_PATTERN(_patt,_expr) \ 53 | do { \ 54 | if (!(_patt)) { \ 55 | vassert(vexGetAllocMode() == VexAllocModeTEMP); \ 56 | vexSetAllocMode(VexAllocModePERM); \ 57 | _patt = (_expr); \ 58 | vexSetAllocMode(VexAllocModeTEMP); \ 59 | vassert(vexGetAllocMode() == VexAllocModeTEMP); \ 60 | } \ 61 | } while (0) 62 | 63 | 64 | /* This type returns the result of a match -- it records what 65 | the binders got instantiated to. */ 66 | 67 | #define N_IRMATCH_BINDERS 4 68 | 69 | typedef 70 | struct { 71 | IRExpr* bindee[N_IRMATCH_BINDERS]; 72 | } 73 | MatchInfo; 74 | 75 | 76 | /* The matching function. p is expected to have zero or more 77 | IRExpr_Binds in it, numbered 0, 1, 2 ... Returns True if a match 78 | succeeded. */ 79 | 80 | extern 81 | Bool matchIRExpr ( MatchInfo* mi, IRExpr* p/*attern*/, IRExpr* e/*xpr*/ ); 82 | 83 | 84 | #endif /* ndef __VEX_IR_MATCH_H */ 85 | 86 | /*---------------------------------------------------------------*/ 87 | /*--- end ir_match.h ---*/ 88 | /*---------------------------------------------------------------*/ 89 | -------------------------------------------------------------------------------- /VEX/priv/ir_opt.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin ir_opt.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #ifndef __VEX_IR_OPT_H 37 | #define __VEX_IR_OPT_H 38 | 39 | #include "libvex_basictypes.h" 40 | #include "libvex_ir.h" 41 | #include "libvex.h" 42 | 43 | /* Top level optimiser entry point. Returns a new BB. Operates 44 | under the control of the global "vex_control" struct and of the 45 | supplied |pxControl| argument. */ 46 | extern 47 | IRSB* do_iropt_BB ( 48 | IRSB* bb, 49 | IRExpr* (*specHelper) (const HChar*, IRExpr**, IRStmt**, Int), 50 | Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 51 | VexRegisterUpdates pxControl, 52 | Addr guest_addr, 53 | VexArch guest_arch 54 | ); 55 | 56 | /* Do a constant folding/propagation pass. */ 57 | extern 58 | IRSB* cprop_BB ( IRSB* ); 59 | 60 | /* Do a dead-code removal pass. bb is destructively modified. */ 61 | extern 62 | void do_deadcode_BB ( IRSB* bb ); 63 | 64 | /* The tree-builder. Make (approximately) maximal safe trees. bb is 65 | destructively modified. Returns (unrelatedly, but useful later on) 66 | the guest address of the highest addressed byte from any insn in 67 | this block, or Addr_MAX if unknown (can that ever happen?) */ 68 | extern 69 | Addr ado_treebuild_BB ( 70 | IRSB* bb, 71 | Bool (*preciseMemExnsFn)(Int,Int,VexRegisterUpdates), 72 | VexRegisterUpdates pxControl 73 | ); 74 | 75 | #endif /* ndef __VEX_IR_OPT_H */ 76 | 77 | /*---------------------------------------------------------------*/ 78 | /*--- end ir_opt.h ---*/ 79 | /*---------------------------------------------------------------*/ 80 | -------------------------------------------------------------------------------- /VEX/priv/main_globals.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin main_globals.c ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #include "libvex_basictypes.h" 37 | 38 | #include "main_util.h" 39 | #include "main_globals.h" 40 | 41 | 42 | /* Global settings for the VEX library. These are the 43 | only library-wide globals. */ 44 | 45 | /* Are we started yet? */ 46 | Bool vex_initdone = False; 47 | 48 | /* failure exit function */ 49 | __attribute__ ((noreturn)) 50 | void (*vex_failure_exit) ( void ) = NULL; 51 | 52 | /* logging output function */ 53 | void (*vex_log_bytes) ( const HChar*, SizeT nbytes ) = NULL; 54 | 55 | /* debug paranoia level */ 56 | Int vex_debuglevel = 0; 57 | 58 | /* trace flags */ 59 | Int vex_traceflags = 0; 60 | 61 | /* Max # guest insns per bb */ 62 | VexControl vex_control = { 0,0,False,0,0,0 }; 63 | 64 | 65 | 66 | /*---------------------------------------------------------------*/ 67 | /*--- end main_globals.c ---*/ 68 | /*---------------------------------------------------------------*/ 69 | -------------------------------------------------------------------------------- /VEX/priv/main_globals.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin main_globals.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #ifndef __VEX_MAIN_GLOBALS_H 37 | #define __VEX_MAIN_GLOBALS_H 38 | 39 | #include "libvex_basictypes.h" 40 | #include "libvex.h" 41 | 42 | 43 | /* Global settings for the VEX library. These are the 44 | only library-wide globals. */ 45 | 46 | /* Are we started yet? */ 47 | extern Bool vex_initdone; 48 | 49 | /* failure exit function */ 50 | __attribute__ ((noreturn)) 51 | extern void (*vex_failure_exit) ( void ); 52 | 53 | /* logging output function */ 54 | extern void (*vex_log_bytes) ( const HChar*, SizeT nbytes ); 55 | 56 | /* debug paranoia level */ 57 | extern Int vex_debuglevel; 58 | 59 | /* trace flags */ 60 | extern Int vex_traceflags; 61 | 62 | /* Optimiser/front-end control */ 63 | extern VexControl vex_control; 64 | 65 | 66 | /* vex_traceflags values */ 67 | #define VEX_TRACE_FE (1 << 7) /* show conversion into IR */ 68 | #define VEX_TRACE_OPT1 (1 << 6) /* show after initial opt */ 69 | #define VEX_TRACE_INST (1 << 5) /* show after instrumentation */ 70 | #define VEX_TRACE_OPT2 (1 << 4) /* show after second opt */ 71 | #define VEX_TRACE_TREES (1 << 3) /* show after tree building */ 72 | #define VEX_TRACE_VCODE (1 << 2) /* show selected insns */ 73 | #define VEX_TRACE_RCODE (1 << 1) /* show after reg-alloc */ 74 | #define VEX_TRACE_ASM (1 << 0) /* show final assembly */ 75 | 76 | 77 | #endif /* ndef __VEX_MAIN_GLOBALS_H */ 78 | 79 | /*---------------------------------------------------------------*/ 80 | /*--- end main_globals.h ---*/ 81 | /*---------------------------------------------------------------*/ 82 | -------------------------------------------------------------------------------- /VEX/priv/main_util.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin main_util.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #ifndef __VEX_MAIN_UTIL_H 37 | #define __VEX_MAIN_UTIL_H 38 | 39 | #include "libvex_basictypes.h" 40 | 41 | 42 | /* Misc. */ 43 | 44 | #define NULL ((void*)0) 45 | 46 | #define LIKELY(x) __builtin_expect(!!(x), 1) 47 | #define UNLIKELY(x) __builtin_expect(!!(x), 0) 48 | 49 | #if !defined(offsetof) 50 | # define offsetof(type,memb) ((SizeT)(HWord)&((type*)0)->memb) 51 | #endif 52 | 53 | // Poor man's static assert 54 | #define STATIC_ASSERT(x) extern int vex__unused_array[(x) ? 1 : -1] 55 | 56 | /* Stuff for panicking and assertion. */ 57 | 58 | #define vassert(expr) \ 59 | ((void) (LIKELY(expr) ? 0 : \ 60 | (vex_assert_fail (#expr, \ 61 | __FILE__, __LINE__, \ 62 | __PRETTY_FUNCTION__), 0))) 63 | 64 | __attribute__ ((__noreturn__)) 65 | extern void vex_assert_fail ( const HChar* expr, const HChar* file, 66 | Int line, const HChar* fn ); 67 | __attribute__ ((__noreturn__)) 68 | extern void vpanic ( const HChar* str ); 69 | 70 | __attribute__ ((__noreturn__)) __attribute__ ((format (printf, 1, 2))) 71 | extern void vfatal ( const HChar* format, ... ); 72 | 73 | 74 | /* Printing */ 75 | 76 | __attribute__ ((format (printf, 1, 2))) 77 | extern UInt vex_printf ( const HChar *format, ... ); 78 | 79 | __attribute__ ((format (printf, 2, 3))) 80 | extern UInt vex_sprintf ( HChar* buf, const HChar *format, ... ); 81 | 82 | 83 | /* String ops */ 84 | 85 | extern Bool vex_streq ( const HChar* s1, const HChar* s2 ); 86 | extern SizeT vex_strlen ( const HChar* str ); 87 | extern void vex_bzero ( void* s, SizeT n ); 88 | 89 | 90 | /* Storage management: clear the area, and allocate from it. */ 91 | 92 | /* By default allocation occurs in the temporary area. However, it is 93 | possible to switch to permanent area allocation if that's what you 94 | want. Permanent area allocation is very limited, tho. */ 95 | 96 | typedef 97 | enum { 98 | VexAllocModeTEMP, 99 | VexAllocModePERM 100 | } 101 | VexAllocMode; 102 | 103 | extern void vexSetAllocMode ( VexAllocMode ); 104 | extern VexAllocMode vexGetAllocMode ( void ); 105 | extern void vexAllocSanityCheck ( void ); 106 | 107 | extern void vexSetAllocModeTEMP_and_clear ( void ); 108 | 109 | /* Allocate in Vex's temporary allocation area. Be careful with this. 110 | You can only call it inside an instrumentation or optimisation 111 | callback that you have previously specified in a call to 112 | LibVEX_Translate. The storage allocated will only stay alive until 113 | translation of the current basic block is complete. 114 | */ 115 | extern HChar* private_LibVEX_alloc_first; 116 | extern HChar* private_LibVEX_alloc_curr; 117 | extern HChar* private_LibVEX_alloc_last; 118 | extern void private_LibVEX_alloc_OOM(void) __attribute__((noreturn)); 119 | 120 | /* Allocated memory as returned by LibVEX_Alloc will be aligned on this 121 | boundary. */ 122 | #define REQ_ALIGN 8 123 | 124 | static inline void* LibVEX_Alloc_inline ( SizeT nbytes ) 125 | { 126 | struct align { 127 | char c; 128 | union { 129 | char c; 130 | short s; 131 | int i; 132 | long l; 133 | long long ll; 134 | float f; 135 | double d; 136 | /* long double is currently not used and would increase alignment 137 | unnecessarily. */ 138 | /* long double ld; */ 139 | void *pto; 140 | void (*ptf)(void); 141 | } x; 142 | }; 143 | 144 | /* Make sure the compiler does no surprise us */ 145 | vassert(offsetof(struct align,x) <= REQ_ALIGN); 146 | 147 | #if 0 148 | /* Nasty debugging hack, do not use. */ 149 | return malloc(nbytes); 150 | #else 151 | HChar* curr; 152 | HChar* next; 153 | SizeT ALIGN; 154 | ALIGN = offsetof(struct align,x) - 1; 155 | nbytes = (nbytes + ALIGN) & ~ALIGN; 156 | curr = private_LibVEX_alloc_curr; 157 | next = curr + nbytes; 158 | if (next >= private_LibVEX_alloc_last) 159 | private_LibVEX_alloc_OOM(); 160 | private_LibVEX_alloc_curr = next; 161 | return curr; 162 | #endif 163 | } 164 | 165 | #endif /* ndef __VEX_MAIN_UTIL_H */ 166 | 167 | /*---------------------------------------------------------------*/ 168 | /*--- main_util.h ---*/ 169 | /*---------------------------------------------------------------*/ 170 | -------------------------------------------------------------------------------- /VEX/priv/s390_defs.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C; c-basic-offset: 3; -*- */ 2 | 3 | /*---------------------------------------------------------------*/ 4 | /*--- begin s390_defs.h ---*/ 5 | /*---------------------------------------------------------------*/ 6 | 7 | /* 8 | This file is part of Valgrind, a dynamic binary instrumentation 9 | framework. 10 | 11 | Copyright IBM Corp. 2010-2013 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | #ifndef __VEX_S390_DEFS_H 32 | #define __VEX_S390_DEFS_H 33 | 34 | 35 | /* Condition code. The encoding of the enumerators matches the value of 36 | the mask field in the various branch opcodes. */ 37 | typedef enum { 38 | S390_CC_NEVER = 0, 39 | S390_CC_OVFL = 1, /* overflow */ 40 | S390_CC_H = 2, /* A > B ; high */ 41 | S390_CC_NLE = 3, /* not low or equal */ 42 | S390_CC_L = 4, /* A < B ; low */ 43 | S390_CC_NHE = 5, /* not high or equal */ 44 | S390_CC_LH = 6, /* low or high */ 45 | S390_CC_NE = 7, /* A != B ; not zero */ 46 | S390_CC_E = 8, /* A == B ; zero */ 47 | S390_CC_NLH = 9, /* not low or high */ 48 | S390_CC_HE = 10, /* A >= B ; high or equal*/ 49 | S390_CC_NL = 11, /* not low */ 50 | S390_CC_LE = 12, /* A <= B ; low or equal */ 51 | S390_CC_NH = 13, /* not high */ 52 | S390_CC_NO = 14, /* not overflow */ 53 | S390_CC_ALWAYS = 15 54 | } s390_cc_t; 55 | 56 | 57 | /* Invert the condition code */ 58 | static __inline__ s390_cc_t 59 | s390_cc_invert(s390_cc_t cond) 60 | { 61 | return S390_CC_ALWAYS - cond; 62 | } 63 | 64 | 65 | /* BFP Rounding mode as it is encoded in the m3 field of certain 66 | instructions (e.g. CFEBR) */ 67 | typedef enum { 68 | S390_BFP_ROUND_PER_FPC = 0, 69 | S390_BFP_ROUND_NEAREST_AWAY = 1, 70 | /* 2 is not allowed */ 71 | S390_BFP_ROUND_PREPARE_SHORT = 3, 72 | S390_BFP_ROUND_NEAREST_EVEN = 4, 73 | S390_BFP_ROUND_ZERO = 5, 74 | S390_BFP_ROUND_POSINF = 6, 75 | S390_BFP_ROUND_NEGINF = 7 76 | } s390_bfp_round_t; 77 | 78 | 79 | /* BFP Rounding mode as it is encoded in bits [29:31] of the FPC register. 80 | Only rounding modes 0..3 are universally supported. Others require 81 | additional hardware facilities. */ 82 | typedef enum { 83 | S390_FPC_BFP_ROUND_NEAREST_EVEN = 0, 84 | S390_FPC_BFP_ROUND_ZERO = 1, 85 | S390_FPC_BFP_ROUND_POSINF = 2, 86 | S390_FPC_BFP_ROUND_NEGINF = 3, 87 | /* 4,5,6 are not allowed */ 88 | S390_FPC_BFP_ROUND_PREPARE_SHORT = 7 /* floating point extension facility */ 89 | } s390_fpc_bfp_round_t; 90 | 91 | 92 | /* DFP Rounding mode as it is encoded in the m3 field of certain 93 | instructions (e.g. CGDTR) */ 94 | typedef enum { 95 | S390_DFP_ROUND_PER_FPC_0 = 0, 96 | S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1 = 1, 97 | S390_DFP_ROUND_PER_FPC_2 = 2, 98 | S390_DFP_ROUND_PREPARE_SHORT_3 = 3, 99 | S390_DFP_ROUND_NEAREST_EVEN_4 = 4, 100 | S390_DFP_ROUND_ZERO_5 = 5, 101 | S390_DFP_ROUND_POSINF_6 = 6, 102 | S390_DFP_ROUND_NEGINF_7 = 7, 103 | S390_DFP_ROUND_NEAREST_EVEN_8 = 8, 104 | S390_DFP_ROUND_ZERO_9 = 9, 105 | S390_DFP_ROUND_POSINF_10 = 10, 106 | S390_DFP_ROUND_NEGINF_11 = 11, 107 | S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12 = 12, 108 | S390_DFP_ROUND_NEAREST_TIE_TOWARD_0 = 13, 109 | S390_DFP_ROUND_AWAY_0 = 14, 110 | S390_DFP_ROUND_PREPARE_SHORT_15 = 15 111 | } s390_dfp_round_t; 112 | 113 | 114 | /* DFP Rounding mode as it is encoded in bits [25:27] of the FPC register. */ 115 | typedef enum { 116 | S390_FPC_DFP_ROUND_NEAREST_EVEN = 0, 117 | S390_FPC_DFP_ROUND_ZERO = 1, 118 | S390_FPC_DFP_ROUND_POSINF = 2, 119 | S390_FPC_DFP_ROUND_NEGINF = 3, 120 | S390_FPC_DFP_ROUND_NEAREST_AWAY_0 = 4, 121 | S390_FPC_DFP_ROUND_NEAREST_TOWARD_0 = 5, 122 | S390_FPC_DFP_ROUND_AWAY_ZERO = 6, 123 | S390_FPC_DFP_ROUND_PREPARE_SHORT = 7 124 | } s390_fpc_dfp_round_t; 125 | 126 | /* PFPO function code as it is encoded in bits [33:55] of GR0 127 | when PFPO insn is executed. */ 128 | typedef enum { 129 | S390_PFPO_F32_TO_D32 = 0x010805, 130 | S390_PFPO_F32_TO_D64 = 0x010905, 131 | S390_PFPO_F32_TO_D128 = 0x010A05, 132 | S390_PFPO_F64_TO_D32 = 0x010806, 133 | S390_PFPO_F64_TO_D64 = 0x010906, 134 | S390_PFPO_F64_TO_D128 = 0x010A06, 135 | S390_PFPO_F128_TO_D32 = 0x010807, 136 | S390_PFPO_F128_TO_D64 = 0x010907, 137 | S390_PFPO_F128_TO_D128 = 0x010A07, 138 | S390_PFPO_D32_TO_F32 = 0x010508, 139 | S390_PFPO_D32_TO_F64 = 0x010608, 140 | S390_PFPO_D32_TO_F128 = 0x010708, 141 | S390_PFPO_D64_TO_F32 = 0x010509, 142 | S390_PFPO_D64_TO_F64 = 0x010609, 143 | S390_PFPO_D64_TO_F128 = 0x010709, 144 | S390_PFPO_D128_TO_F32 = 0x01050A, 145 | S390_PFPO_D128_TO_F64 = 0x01060A, 146 | S390_PFPO_D128_TO_F128 = 0x01070A 147 | } s390_pfpo_function_t; 148 | 149 | /* The length of the longest mnemonic: locgrnhe */ 150 | #define S390_MAX_MNEMONIC_LEN 8 151 | 152 | 153 | /*---------------------------------------------------------------*/ 154 | /*--- end s390_defs.h ---*/ 155 | /*---------------------------------------------------------------*/ 156 | 157 | #endif /* __VEX_S390_DEFS_H */ 158 | -------------------------------------------------------------------------------- /VEX/priv/s390_disasm.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C; c-basic-offset: 3; -*- */ 2 | 3 | /*---------------------------------------------------------------*/ 4 | /*--- begin s390_disasm.h ---*/ 5 | /*---------------------------------------------------------------*/ 6 | 7 | /* 8 | This file is part of Valgrind, a dynamic binary instrumentation 9 | framework. 10 | 11 | Copyright IBM Corp. 2010-2013 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | #ifndef __VEX_S390_DISASM_H 32 | #define __VEX_S390_DISASM_H 33 | 34 | #include "libvex_basictypes.h" 35 | 36 | /* Macros to encode a command for s390_disasm. */ 37 | #undef P 38 | #define P(a) (S390_ARG_##a) 39 | #undef ENC1 40 | #define ENC1(a) ((P(DONE) << 4) | P(a)) 41 | #undef ENC2 42 | #define ENC2(a,b) ((P(DONE) << 8) | (P(b) << 4) | P(a)) 43 | #undef ENC3 44 | #define ENC3(a,b,c) ((P(DONE) << 12) | (P(c) << 8) | (P(b) << 4) | P(a)) 45 | #undef ENC4 46 | #define ENC4(a,b,c,d) ((P(DONE) << 16) | (P(d) << 12) | (P(c) << 8) | \ 47 | (P(b) << 4) | P(a)) 48 | #undef ENC5 49 | #define ENC5(a,b,c,d,e) ((P(DONE) << 20) | (P(e) << 16) | (P(d) << 12) | \ 50 | (P(c) << 8) | (P(b) << 4) | P(a)) 51 | #undef ENC6 52 | #define ENC6(a,b,c,d,e,f) ((P(DONE) << 24) | (P(f) << 20) | (P(e) << 16) | \ 53 | (P(d) << 12) | (P(c) << 8) | (P(b) << 4) | P(a)) 54 | 55 | /* The different kinds of operands in an asm insn */ 56 | enum { 57 | S390_ARG_DONE = 0, 58 | S390_ARG_GPR = 1, 59 | S390_ARG_FPR = 2, 60 | S390_ARG_AR = 3, 61 | S390_ARG_INT = 4, 62 | S390_ARG_UINT = 5, 63 | S390_ARG_PCREL = 6, 64 | S390_ARG_SDXB = 7, 65 | S390_ARG_UDXB = 8, 66 | S390_ARG_UDLB = 9, 67 | S390_ARG_CABM = 10, 68 | S390_ARG_MNM = 11, 69 | S390_ARG_XMNM = 12 70 | }; 71 | 72 | /* The different kinds of extended mnemonics */ 73 | enum { 74 | S390_XMNM_CAB = 0, 75 | S390_XMNM_BCR = 1, 76 | S390_XMNM_BC = 2, 77 | S390_XMNM_BRC = 3, 78 | S390_XMNM_BRCL = 4, 79 | S390_XMNM_LOCR = 5, 80 | S390_XMNM_LOCGR = 6, 81 | S390_XMNM_LOC = 7, 82 | S390_XMNM_LOCG = 8, 83 | S390_XMNM_STOC = 9, 84 | S390_XMNM_STOCG = 10 85 | }; 86 | 87 | void s390_disasm(UInt command, ...); 88 | 89 | /*---------------------------------------------------------------*/ 90 | /*--- end s390_disasm.h ---*/ 91 | /*---------------------------------------------------------------*/ 92 | 93 | #endif /* __VEX_S390_DISASM_H */ 94 | -------------------------------------------------------------------------------- /VEX/pub/libvex_emnote.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin libvex_emnote.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #ifndef __LIBVEX_EMNOTE_H 37 | #define __LIBVEX_EMNOTE_H 38 | 39 | #include "libvex_basictypes.h" 40 | 41 | /* VEX can sometimes generate code which returns to the dispatcher 42 | with the guest state pointer set to VEX_TRC_JMP_EMWARN or 43 | VEX_TRC_JMP_EMFAIL. This means that VEX is trying to tell Valgrind 44 | something noteworthy about emulation progress. For example, that Valgrind 45 | is doing imprecise emulation in some sense. The guest's pseudo-register 46 | "guest_EMNOTE" will hold a value of type VexEmNote, which describes 47 | the nature of the warning. Currently the limitations that are 48 | warned about apply primarily to floating point support. 49 | 50 | All guest states must have a 32-bit (UInt) guest_EMNOTE pseudo- 51 | register, that emulation warnings can be written in to. 52 | 53 | Note that guest_EMNOTE only carries a valid value at the jump 54 | marked as VEX_TRC_JMP_EMWARN / VEX_TRC_JMP_EMFAIL. You can't assume 55 | it will continue to carry a valid value from any amount of time after 56 | the jump. 57 | */ 58 | 59 | typedef 60 | enum { 61 | /* no note indicated */ 62 | EmNote_NONE=0, 63 | 64 | /* unmasking x87 FP exceptions is not supported */ 65 | EmWarn_X86_x87exns, 66 | 67 | /* change of x87 FP precision away from 64-bit (mantissa) */ 68 | EmWarn_X86_x87precision, 69 | 70 | /* unmasking SSE FP exceptions is not supported */ 71 | EmWarn_X86_sseExns, 72 | 73 | /* setting mxcsr.fz is not supported */ 74 | EmWarn_X86_fz, 75 | 76 | /* setting mxcsr.daz is not supported */ 77 | EmWarn_X86_daz, 78 | 79 | /* settings to %eflags.ac (alignment check) are noted but ignored */ 80 | EmWarn_X86_acFlag, 81 | 82 | /* unmasking PPC32/64 FP exceptions is not supported */ 83 | EmWarn_PPCexns, 84 | 85 | /* overflow/underflow of the PPC64 _REDIR stack (ppc64 only) */ 86 | EmWarn_PPC64_redir_overflow, 87 | EmWarn_PPC64_redir_underflow, 88 | 89 | /* insn specifies a rounding mode other than "according to FPC" 90 | which requires the floating point extension facility. But that 91 | facility is not available on this host */ 92 | EmWarn_S390X_fpext_rounding, 93 | 94 | /* insn (e.g. srnmb) specifies an invalid rounding mode */ 95 | EmWarn_S390X_invalid_rounding, 96 | 97 | /* stfle insn is not supported on this host */ 98 | EmFail_S390X_stfle, 99 | 100 | /* stckf insn is not supported on this host */ 101 | EmFail_S390X_stckf, 102 | 103 | /* ecag insn is not supported on this host */ 104 | EmFail_S390X_ecag, 105 | 106 | /* pfpo insn is not supported on this host */ 107 | EmFail_S390X_pfpo, 108 | 109 | /* DFP insns are not supported on this host */ 110 | EmFail_S390X_DFP_insn, 111 | 112 | /* insn needs floating point extension facility which is not 113 | available on this host */ 114 | EmFail_S390X_fpext, 115 | 116 | /* GPR 0 contains invalid rounding mode for PFPO instruction */ 117 | EmFail_S390X_invalid_PFPO_rounding_mode, 118 | 119 | /* The function code specified in GPR 0 executed by PFPO 120 | instruction is invalid */ 121 | EmFail_S390X_invalid_PFPO_function, 122 | 123 | EmNote_NUMBER 124 | } 125 | VexEmNote; 126 | 127 | 128 | /* Produces a short string describing the warning. */ 129 | extern const HChar* LibVEX_EmNote_string ( VexEmNote ); 130 | 131 | 132 | #endif /* ndef __LIBVEX_EMNOTE_H */ 133 | 134 | /*---------------------------------------------------------------*/ 135 | /*--- libvex_emnote.h ---*/ 136 | /*---------------------------------------------------------------*/ 137 | -------------------------------------------------------------------------------- /VEX/pub/libvex_s390x_common.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: C; c-basic-offset: 3; -*- */ 2 | 3 | /*--------------------------------------------------------------------*/ 4 | /*--- Common defs for s390x libvex_s390x_common.h ---*/ 5 | /*--------------------------------------------------------------------*/ 6 | 7 | /* 8 | This file is part of Valgrind, a dynamic binary instrumentation 9 | framework. 10 | 11 | Copyright IBM Corp. 2010-2013 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | */ 30 | 31 | #ifndef __LIBVEX_PUB_S390X_H 32 | #define __LIBVEX_PUB_S390X_H 33 | 34 | /* This file includes definitions for s390. 35 | 36 | It must be suitable for inclusion in assembler source files. */ 37 | 38 | 39 | /*--------------------------------------------------------------*/ 40 | /*--- Dedicated registers ---*/ 41 | /*--------------------------------------------------------------*/ 42 | 43 | #define S390_REGNO_RETURN_VALUE 2 44 | #define S390_REGNO_TCHAIN_SCRATCH 12 45 | #define S390_REGNO_GUEST_STATE_POINTER 13 46 | #define S390_REGNO_LINK_REGISTER 14 47 | #define S390_REGNO_STACK_POINTER 15 48 | 49 | 50 | /*--------------------------------------------------------------*/ 51 | /*--- Offsets in the stack frame allocated by the dispatcher ---*/ 52 | /*--------------------------------------------------------------*/ 53 | 54 | /* Dispatcher will save 8 FPRs at offsets 160 + 0 ... 160 + 56 */ 55 | 56 | /* Where the dispatcher saves the r2 contents. */ 57 | #define S390_OFFSET_SAVED_R2 160+80 58 | 59 | /* Where client's FPC register is saved. */ 60 | #define S390_OFFSET_SAVED_FPC_C 160+72 61 | 62 | /* Where valgrind's FPC register is saved. */ 63 | #define S390_OFFSET_SAVED_FPC_V 160+64 64 | 65 | /* Size of frame allocated by VG_(disp_run_translations) 66 | Need size for 67 | 8 FPRs 68 | + 1 GPR (SAVED_R2) 69 | + 2 FPCs (SAVED_FPC_C and SAVED_FPC_V). 70 | 71 | Additionally, we need a standard frame for helper functions being called 72 | from client code. (See figure 1-16 in zSeries ABI) */ 73 | #define S390_INNERLOOP_FRAME_SIZE ((8+1+2)*8 + 160) 74 | 75 | 76 | /*--------------------------------------------------------------*/ 77 | /*--- Facility bits ---*/ 78 | /*--------------------------------------------------------------*/ 79 | 80 | /* The value of the macro is the number of the facility bit as per POP. */ 81 | #define S390_FAC_MSA 17 // message-security-assist 82 | #define S390_FAC_LDISP 18 // long displacement 83 | #define S390_FAC_HFPMAS 20 // HFP multiply-and-add-subtract 84 | #define S390_FAC_EIMM 21 // extended immediate 85 | #define S390_FAC_HFPUNX 23 // HFP unnormalized extension 86 | #define S390_FAC_ETF2 24 // ETF2-enhancement 87 | #define S390_FAC_STCKF 25 // store clock fast insn 88 | #define S390_FAC_PENH 26 // parsing-enhancement 89 | #define S390_FAC_ETF3 30 // ETF3-enhancement 90 | #define S390_FAC_XCPUT 31 // extract-CPU-time 91 | #define S390_FAC_GIE 34 // general insn extension 92 | #define S390_FAC_EXEXT 35 // execute extension 93 | #define S390_FAC_FPEXT 37 // floating-point extension 94 | #define S390_FAC_FPSE 41 // floating-point support enhancement 95 | #define S390_FAC_DFP 42 // decimal floating point 96 | #define S390_FAC_PFPO 44 // perform floating point operation insn 97 | #define S390_FAC_HIGHW 45 // high-word extension 98 | #define S390_FAC_LSC 45 // load/store on condition 99 | #define S390_FAC_DFPZC 48 // DFP zoned-conversion 100 | #define S390_FAC_MISC 49 // miscellaneous insn 101 | #define S390_FAC_CTREXE 50 // constrained transactional execution 102 | #define S390_FAC_TREXE 73 // transactional execution 103 | #define S390_FAC_MSA4 77 // message-security-assist 4 104 | 105 | 106 | /*--------------------------------------------------------------*/ 107 | /*--- Miscellaneous ---*/ 108 | /*--------------------------------------------------------------*/ 109 | 110 | /* Number of arguments that can be passed in registers */ 111 | #define S390_NUM_GPRPARMS 5 112 | 113 | /* Number of double words needed to store all facility bits. */ 114 | #define S390_NUM_FACILITY_DW 2 115 | 116 | #endif /* __LIBVEX_PUB_S390X_H */ 117 | 118 | /*--------------------------------------------------------------------*/ 119 | /*--- end libvex_s390x_common.h ---*/ 120 | /*--------------------------------------------------------------------*/ 121 | -------------------------------------------------------------------------------- /VEX/pub/libvex_trc_values.h: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin libvex_trc_values.h ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | /* 7 | This file is part of Valgrind, a dynamic binary instrumentation 8 | framework. 9 | 10 | Copyright (C) 2004-2013 OpenWorks LLP 11 | info@open-works.net 12 | 13 | This program is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU General Public License as 15 | published by the Free Software Foundation; either version 2 of the 16 | License, or (at your option) any later version. 17 | 18 | This program is distributed in the hope that it will be useful, but 19 | WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | General Public License for more details. 22 | 23 | You should have received a copy of the GNU General Public License 24 | along with this program; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 26 | 02110-1301, USA. 27 | 28 | The GNU General Public License is contained in the file COPYING. 29 | 30 | Neither the names of the U.S. Department of Energy nor the 31 | University of California nor the names of its contributors may be 32 | used to endorse or promote products derived from this software 33 | without prior written permission. 34 | */ 35 | 36 | #ifndef __LIBVEX_TRC_VALUES_H 37 | #define __LIBVEX_TRC_VALUES_H 38 | 39 | 40 | /* Magic values that the guest state pointer might be set to when 41 | returning to the dispatcher. The only other legitimate value is to 42 | point to the start of the thread's VEX guest state. 43 | 44 | This file may get included in assembly code, so do not put 45 | C-specific constructs in it. 46 | 47 | These values should be 61 or above so as not to conflict 48 | with Valgrind's VG_TRC_ values, which are 60 or below. 49 | */ 50 | 51 | #define VEX_TRC_JMP_INVALICACHE 61 /* invalidate icache (translations) 52 | before continuing */ 53 | #define VEX_TRC_JMP_FLUSHDCACHE 103 /* flush dcache before continuing */ 54 | 55 | #define VEX_TRC_JMP_NOREDIR 81 /* jump to undirected guest addr */ 56 | #define VEX_TRC_JMP_SIGTRAP 85 /* deliver trap (SIGTRAP) before 57 | continuing */ 58 | #define VEX_TRC_JMP_SIGSEGV 87 /* deliver segv (SIGSEGV) before 59 | continuing */ 60 | #define VEX_TRC_JMP_SIGBUS 93 /* deliver SIGBUS before continuing */ 61 | 62 | #define VEX_TRC_JMP_SIGFPE_INTDIV 97 /* deliver SIGFPE (integer divide 63 | by zero) before continuing */ 64 | 65 | #define VEX_TRC_JMP_SIGFPE_INTOVF 99 /* deliver SIGFPE (integer overflow) 66 | before continuing */ 67 | 68 | #define VEX_TRC_JMP_SIGILL 101 /* deliver SIGILL (Illegal instruction) 69 | before continuing */ 70 | 71 | #define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before 72 | continuing */ 73 | #define VEX_TRC_JMP_EMFAIL 83 /* emulation fatal error; abort system */ 74 | 75 | #define VEX_TRC_JMP_CLIENTREQ 65 /* do a client req before continuing */ 76 | #define VEX_TRC_JMP_YIELD 67 /* yield to thread sched 77 | before continuing */ 78 | #define VEX_TRC_JMP_NODECODE 69 /* next instruction is not decodable */ 79 | #define VEX_TRC_JMP_MAPFAIL 71 /* address translation failed */ 80 | 81 | #define VEX_TRC_JMP_SYS_SYSCALL 73 /* do syscall before continuing */ 82 | #define VEX_TRC_JMP_SYS_INT32 75 /* do syscall before continuing */ 83 | #define VEX_TRC_JMP_SYS_INT128 77 /* do syscall before continuing */ 84 | #define VEX_TRC_JMP_SYS_INT129 89 /* do syscall before continuing */ 85 | #define VEX_TRC_JMP_SYS_INT130 91 /* do syscall before continuing */ 86 | 87 | #define VEX_TRC_JMP_SYS_SYSENTER 79 /* do syscall before continuing */ 88 | 89 | #define VEX_TRC_JMP_BORING 95 /* return to sched, but just 90 | keep going; no special action */ 91 | 92 | #endif /* ndef __LIBVEX_TRC_VALUES_H */ 93 | 94 | /*---------------------------------------------------------------*/ 95 | /*--- libvex_trc_values.h ---*/ 96 | /*---------------------------------------------------------------*/ 97 | -------------------------------------------------------------------------------- /VEX/switchback/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CC=aarch64-linux-gnu-gcc 3 | 4 | all: switchback.c linker.c linker.h 5 | $CC -m64 -Wall -O -g -o switchback switchback.c linker.c \ 6 | ../libvex_ppc64_linux.a 7 | 8 | test_ppc: 9 | $CC -Wall -m64 -mregnames -O -c test_ppc_jm1.c 10 | 11 | clean: 12 | rm -f switchback switchback.o linker.o 13 | -------------------------------------------------------------------------------- /VEX/switchback/linker.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | void* linker_top_level_LINK ( int n_object_names, char** object_names ); 4 | 5 | extern void* mymalloc ( int ); 6 | -------------------------------------------------------------------------------- /VEX/switchback/test_hello.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | static void bar ( void*(*service)(int,int) ) 4 | { 5 | int i; 6 | for (i = 0; i < 100000; i++) ; 7 | service(1, 'h'); 8 | service(1, 'e'); 9 | service(1, 'l'); 10 | service(1, 'l'); 11 | service(1, 'o'); 12 | service(1, '\n'); 13 | } 14 | 15 | void entry ( void*(*service)(int,int) ) 16 | { 17 | bar(service); 18 | service(0,0); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /VEX/switchback/test_simple.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | static void bar ( void*(*service)(int,int) ) 4 | { 5 | __asm__ __volatile__ ("addi 17, 14, 5"); 6 | } 7 | 8 | void entry ( void*(*service)(int,int) ) 9 | { 10 | bar(service); 11 | service(0,0); 12 | } 13 | -------------------------------------------------------------------------------- /VEX/test/fldenv.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | void do_fstenv ( void* p ) 6 | { 7 | asm("movl 8(%esp), %eax ; fstenv (%eax)"); 8 | } 9 | 10 | void do_fldenv ( void* p ) 11 | { 12 | asm("movl 8(%esp), %eax ; fldenv (%eax)"); 13 | } 14 | 15 | int main ( void ) 16 | { 17 | int i; 18 | unsigned short* buf = malloc(14*sizeof(short)); 19 | for (i = 0; i < 14; i++) 20 | buf[i] = i; 21 | buf[0] = 0x037f; 22 | 23 | do_fldenv(buf); 24 | do_fstenv(buf); 25 | for (i = 0; i < 14; i++) { 26 | printf("%04x ", buf[i]); 27 | if (i > 0 && ((i % 12) == 11)) 28 | printf("\n"); 29 | } 30 | printf("\n"); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /VEX/test/fp1.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | double a[10]; 5 | 6 | int main ( void ) 7 | { 8 | int i; 9 | double s; 10 | for (i = 0; i < 10; i++) 11 | a[i] = 11.11 * i; 12 | s = 0.0; 13 | for (i = 0; i < 10; i++) 14 | s += a[i]; 15 | printf("result = %f\n", s); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /VEX/test/fp1.s: -------------------------------------------------------------------------------- 1 | .file "fp1.c" 2 | .version "01.01" 3 | gcc2_compiled.: 4 | .section .rodata.str1.1,"aMS",@progbits,1 5 | .LC2: 6 | .string "result = %f\n" 7 | .section .rodata.cst8,"aM",@progbits,8 8 | .align 8 9 | .LC0: 10 | .long 0xeb851eb8,0x40263851 11 | .text 12 | .align 4 13 | .globl main 14 | .type main,@function 15 | main: 16 | pushl %ebp 17 | movl %esp, %ebp 18 | subl $8, %esp 19 | movl $0, %eax 20 | movl $a, %edx 21 | fldl .LC0 22 | .p2align 2 23 | .L21: 24 | fld %st(0) 25 | pushl %eax 26 | fimull (%esp) 27 | popl %eax 28 | fstpl (%edx,%eax,8) 29 | incl %eax 30 | cmpl $9, %eax 31 | jle .L21 32 | fstp %st(0) 33 | fldz 34 | movl $0, %eax 35 | movl $a, %edx 36 | .p2align 2 37 | .L26: 38 | faddl (%edx,%eax,8) 39 | incl %eax 40 | cmpl $9, %eax 41 | jle .L26 42 | subl $12, %esp 43 | fstpl (%esp) 44 | pushl $.LC2 45 | call printf 46 | movl $0, %eax 47 | leave 48 | ret 49 | .Lfe1: 50 | .size main,.Lfe1-main 51 | .comm a,80,32 52 | .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.3 2.96-110)" 53 | -------------------------------------------------------------------------------- /VEX/test/fpconst.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | void do_fld1 ( void* p ) 6 | { 7 | asm __volatile__("fninit"); 8 | asm __volatile__("fld1"); 9 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 10 | } 11 | 12 | void do_fldl2t ( void* p ) 13 | { 14 | asm __volatile__("fninit"); 15 | asm __volatile__("fldl2t"); 16 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 17 | } 18 | 19 | void do_fldl2e ( void* p ) 20 | { 21 | asm __volatile__("fninit"); 22 | asm __volatile__("fldl2e"); 23 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 24 | } 25 | 26 | void do_fldpi ( void* p ) 27 | { 28 | asm __volatile__("fninit"); 29 | asm __volatile__("fldpi"); 30 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 31 | } 32 | 33 | void do_fldlg2 ( void* p ) 34 | { 35 | asm __volatile__("fninit"); 36 | asm __volatile__("fldlg2"); 37 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 38 | } 39 | 40 | void do_fldln2 ( void* p ) 41 | { 42 | asm __volatile__("fninit"); 43 | asm __volatile__("fldln2"); 44 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 45 | } 46 | 47 | void do_fldz ( void* p ) 48 | { 49 | asm __volatile__("fninit"); 50 | asm __volatile__("fldz"); 51 | asm __volatile__("fstpl (%0)" : : "r" (p) : "memory" ); 52 | } 53 | 54 | typedef unsigned char UChar; 55 | 56 | void foo ( void (*f)(void*), char* name ) 57 | { 58 | int i; 59 | UChar* b = malloc(8); 60 | f(b); 61 | printf("%s IRConst_F64i(0x", name); 62 | for (i = 7; i >= 0; i--) 63 | printf("%02x", (int)b[i]); 64 | printf(")\n"); 65 | } 66 | 67 | int main ( void ) 68 | { 69 | foo( do_fld1, "fld1 "); 70 | foo( do_fldl2t, "fldl2t"); 71 | foo( do_fldl2e, "fldl2e"); 72 | foo( do_fldpi, "fldpi "); 73 | foo( do_fldlg2, "fldlg2"); 74 | foo( do_fldln2, "fldln2"); 75 | foo( do_fldz, "fldz "); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /VEX/test/fpgames.s: -------------------------------------------------------------------------------- 1 | .file "fpgames.c" 2 | .version "01.01" 3 | gcc2_compiled.: 4 | .section .rodata.str1.1,"aMS",@progbits,1 5 | .LC0: 6 | .string "%02x " 7 | .LC1: 8 | .string "\n" 9 | .text 10 | .align 4 11 | .globl show 12 | .type show,@function 13 | show: 14 | pushl %ebp 15 | movl %esp, %ebp 16 | pushl %ebx 17 | subl $4, %esp 18 | movl $0, %ebx 19 | .p2align 2 20 | .L21: 21 | subl $8, %esp 22 | movzbl st(%ebx), %eax 23 | pushl %eax 24 | pushl $.LC0 25 | call printf 26 | addl $16, %esp 27 | testl %ebx, %ebx 28 | jle .L20 29 | movl %ebx, %eax 30 | andl $3, %eax 31 | cmpl $3, %eax 32 | jne .L20 33 | subl $12, %esp 34 | pushl $.LC1 35 | call printf 36 | addl $16, %esp 37 | .L20: 38 | incl %ebx 39 | cmpl $27, %ebx 40 | jle .L21 41 | movl $0, %ebx 42 | .p2align 2 43 | .L27: 44 | subl $8, %esp 45 | movzbl st+28(%ebx), %eax 46 | pushl %eax 47 | pushl $.LC0 48 | call printf 49 | addl $16, %esp 50 | testl %ebx, %ebx 51 | jle .L26 52 | movl $10, %edx 53 | movl %ebx, %eax 54 | movl %edx, %ecx 55 | cltd 56 | idivl %ecx 57 | cmpl $9, %edx 58 | jne .L26 59 | subl $12, %esp 60 | pushl $.LC1 61 | call printf 62 | addl $16, %esp 63 | .L26: 64 | incl %ebx 65 | cmpl $79, %ebx 66 | jle .L27 67 | subl $12, %esp 68 | pushl $.LC1 69 | call printf 70 | movl -4(%ebp), %ebx 71 | leave 72 | ret 73 | .Lfe1: 74 | .size show,.Lfe1-show 75 | .section .rodata.str1.1,"aMS",@progbits,1 76 | .LC2: 77 | .string "\n\n" 78 | .text 79 | .align 4 80 | .globl main 81 | .type main,@function 82 | main: 83 | pushl %ebp 84 | movl %esp, %ebp 85 | subl $8, %esp 86 | #APP 87 | finit ; fnsave st 88 | #NO_APP 89 | call show 90 | subl $12, %esp 91 | pushl $.LC2 92 | call printf 93 | #APP 94 | fld1 ; fnsave st 95 | #NO_APP 96 | call show 97 | movl $0, %eax 98 | leave 99 | ret 100 | .Lfe2: 101 | .size main,.Lfe2-main 102 | .comm st,108,32 103 | .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.3 2.96-110)" 104 | -------------------------------------------------------------------------------- /VEX/test/fpspeed.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | int main ( void ) 7 | { 8 | int i, j; 9 | double s, r; 10 | s = 0.0; 11 | double* a1 = malloc(1000 * sizeof(double)); 12 | double* a2 = malloc(1000 * sizeof(double)); 13 | for (i = 0; i < 1000; i++) { 14 | a1[i] = s; 15 | s += 0.3374893482232; 16 | a2[i] = s; 17 | } 18 | 19 | s = 0.0; 20 | r = 0.0; 21 | for (j = 0; j < 5000; j++) { 22 | for (i = 0; i < 1000; i++) { 23 | s += (a1[i] - a2[i]) * (a1[i] + a2[i]) - sqrt(r + 1.0); 24 | r += 0.001; 25 | } 26 | } 27 | printf("s = %f, r = %f\n", s, r ); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /VEX/test/fpucw.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | void fldcw_default ( void ) 5 | { 6 | asm(" pushw $0x037F ; fldcw (%esp) ; addl $2, %esp"); 7 | } 8 | 9 | void fldcw_exns ( void ) 10 | { 11 | asm(" pushw $0x037E ; fldcw (%esp) ; addl $2, %esp"); 12 | } 13 | 14 | void fldcw_precision ( void ) 15 | { 16 | asm(" pushw $0x007F ; fldcw (%esp) ; addl $2, %esp"); 17 | } 18 | 19 | void fldcw_rounding ( void ) 20 | { 21 | asm(" pushw $0x077F ; fldcw (%esp) ; addl $2, %esp"); 22 | } 23 | 24 | int main ( void ) 25 | { 26 | printf("default\n"); 27 | fldcw_default(); 28 | printf("\n"); 29 | 30 | printf("exns\n"); 31 | fldcw_exns(); 32 | printf("\n"); 33 | 34 | printf("precision\n"); 35 | fldcw_precision(); 36 | printf("\n"); 37 | 38 | printf("rounding\n"); 39 | fldcw_rounding(); 40 | printf("\n"); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /VEX/test/frstor.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | void do_fsave_interesting_stuff ( void* p ) 6 | { 7 | asm __volatile__("fninit"); 8 | asm __volatile__("fldpi"); 9 | asm __volatile__("fld1"); 10 | asm __volatile__("fldln2"); 11 | asm __volatile__("fsave (%0)" : : "r" (p) : "memory" ); 12 | } 13 | 14 | void do_fsave ( void* p ) 15 | { 16 | asm __volatile__("fsave (%0)" : : "r" (p) : "memory" ); 17 | } 18 | 19 | void do_frstor ( void* p ) 20 | { 21 | asm __volatile__("frstor (%0)" : : "r" (p) : "memory" ); 22 | } 23 | 24 | 25 | int isFPLsbs ( int i ) 26 | { 27 | int q; 28 | q = 0; if (i == q || i == q+1) return 1; 29 | q = 10; if (i == q || i == q+1) return 1; 30 | q = 20; if (i == q || i == q+1) return 1; 31 | q = 30; if (i == q || i == q+1) return 1; 32 | q = 40; if (i == q || i == q+1) return 1; 33 | q = 50; if (i == q || i == q+1) return 1; 34 | q = 60; if (i == q || i == q+1) return 1; 35 | q = 70; if (i == q || i == q+1) return 1; 36 | return 0; 37 | } 38 | 39 | void show_fpustate ( unsigned char* buf, int hide64to80 ) 40 | { 41 | int i; 42 | printf(" 0 "); 43 | for (i = 0; i < 14; i++) 44 | printf("%02x ", buf[i]); 45 | printf("\n"); 46 | 47 | printf(" 14 "); 48 | for (i = 14; i < 28; i++) 49 | printf("%02x ", buf[i]); 50 | printf("\n"); 51 | 52 | for (i = 0; i < 80; i++) { 53 | if ((i % 10) == 0) 54 | printf("%3d ", i+28); 55 | if (hide64to80 && isFPLsbs(i)) 56 | printf("xx "); 57 | else 58 | printf("%02x ", buf[i+28]); 59 | if (i > 0 && ((i % 10) == 9)) 60 | printf("\n"); 61 | } 62 | } 63 | 64 | int main ( int argc, char** argv ) 65 | { 66 | unsigned short* buf1 = malloc(54*sizeof(short)); 67 | unsigned short* buf2 = malloc(54*sizeof(short)); 68 | int xx = argc > 1; 69 | printf("Re-run with any arg to suppress least-significant\n" 70 | " 16 bits of FP numbers\n"); 71 | 72 | /* Create an initial image. */ 73 | do_fsave_interesting_stuff(buf1); 74 | show_fpustate( (unsigned char*)buf1, xx ); 75 | 76 | /* Reload it into buf2. */ 77 | do_frstor(buf1); 78 | do_fsave(buf2); 79 | show_fpustate( (unsigned char*)buf2, xx ); 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /VEX/test/fsave.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | void do_fsave ( void* p ) 6 | { 7 | asm __volatile__("fninit"); 8 | asm __volatile__("fldpi"); 9 | asm __volatile__("fld1"); 10 | asm __volatile__("fldln2"); 11 | asm __volatile__("fsave (%0)" : : "r" (p) : "memory" ); 12 | } 13 | 14 | int isFPLsbs ( int i ) 15 | { 16 | int q; 17 | q = 0; if (i == q || i == q+1) return 1; 18 | q = 10; if (i == q || i == q+1) return 1; 19 | q = 20; if (i == q || i == q+1) return 1; 20 | q = 30; if (i == q || i == q+1) return 1; 21 | q = 40; if (i == q || i == q+1) return 1; 22 | q = 50; if (i == q || i == q+1) return 1; 23 | q = 60; if (i == q || i == q+1) return 1; 24 | q = 70; if (i == q || i == q+1) return 1; 25 | return 0; 26 | } 27 | 28 | void show_fpustate ( unsigned char* buf, int hide64to80 ) 29 | { 30 | int i; 31 | printf(" 0 "); 32 | for (i = 0; i < 14; i++) 33 | printf("%02x ", buf[i]); 34 | printf("\n"); 35 | 36 | printf(" 14 "); 37 | for (i = 14; i < 28; i++) 38 | printf("%02x ", buf[i]); 39 | printf("\n"); 40 | 41 | for (i = 0; i < 80; i++) { 42 | if ((i % 10) == 0) 43 | printf("%3d ", i+28); 44 | if (hide64to80 && isFPLsbs(i)) 45 | printf("xx "); 46 | else 47 | printf("%02x ", buf[i+28]); 48 | if (i > 0 && ((i % 10) == 9)) 49 | printf("\n"); 50 | } 51 | } 52 | 53 | int main ( int argc, char** argv ) 54 | { 55 | int i; 56 | unsigned char* buf = malloc(108); 57 | int xx = argc > 1; 58 | printf("Re-run with any arg to suppress least-significant\n" 59 | " 16 bits of FP numbers\n"); 60 | for (i = 0; i < 108; i++) 61 | buf[i] = 0xAA; 62 | 63 | /* dump FPU state in buf, and show it. */ 64 | do_fsave(buf); 65 | show_fpustate( buf, xx ); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /VEX/test/fstenv.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | void do_fstenv ( void* p ) 6 | { 7 | asm("fldpi ; fld1; fldln2 ; movl 8(%esp), %eax ; fstenv (%eax)"); 8 | } 9 | 10 | int main ( void ) 11 | { 12 | int i; 13 | unsigned int* buf = malloc(7*sizeof(int)); 14 | do_fstenv(buf); 15 | for (i = 0; i < 7; i++) { 16 | printf("%08x ", buf[i]); 17 | if (i > 0 && ((i % 6) == 5)) 18 | printf("\n"); 19 | } 20 | printf("\n"); 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /VEX/test/fxsave.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | const unsigned int vec0[4] 8 | = { 0x12345678, 0x11223344, 0x55667788, 0x87654321 }; 9 | 10 | const unsigned int vec1[4] 11 | = { 0xABCDEF01, 0xAABBCCDD, 0xEEFF0011, 0x10FEDCBA }; 12 | 13 | const unsigned int vecZ[4] 14 | = { 0, 0, 0, 0 }; 15 | 16 | void do_fxsave ( void* p ) { 17 | asm __volatile__("fxsave (%0)" : : "r" (p) : "memory" ); 18 | } 19 | 20 | void do_fxrstor ( void* p ) { 21 | asm __volatile__("fxrstor (%0)" : : "r" (p) : "memory" ); 22 | } 23 | 24 | void do_zeroise ( void ) 25 | { 26 | asm __volatile__("finit"); 27 | asm __volatile__( 28 | "fldz\n\t" 29 | "fldz\n\t" 30 | "fldz\n\t" 31 | "fldz\n\t" 32 | "fldz\n\t" 33 | "fldz\n\t" 34 | "fldz\n\t" 35 | "fldz\n\t" 36 | "finit\n"); 37 | asm __volatile__("movups vecZ, %xmm0"); 38 | asm __volatile__("movups vecZ, %xmm1"); 39 | asm __volatile__("movups vecZ, %xmm2"); 40 | asm __volatile__("movups vecZ, %xmm3"); 41 | asm __volatile__("movups vecZ, %xmm4"); 42 | asm __volatile__("movups vecZ, %xmm5"); 43 | asm __volatile__("movups vecZ, %xmm6"); 44 | asm __volatile__("movups vecZ, %xmm7"); 45 | asm __volatile__( 46 | "pushl $0\n\t" 47 | "ldmxcsr 0(%esp)\n\t" 48 | "addl $4,%esp\n"); 49 | } 50 | 51 | /* set up the FP and SSE state, and then dump it. */ 52 | void do_setup_then_fxsave ( void* p ) 53 | { 54 | asm __volatile__("finit"); 55 | asm __volatile__("fldpi"); 56 | asm __volatile__("fld1"); 57 | asm __volatile__("fldln2"); 58 | asm __volatile__("fldlg2"); 59 | asm __volatile__("fld %st(3)"); 60 | asm __volatile__("fld %st(3)"); 61 | asm __volatile__("movups vec0, %xmm0"); 62 | asm __volatile__("movups vec1, %xmm1"); 63 | asm __volatile__("xorps %xmm2, %xmm2"); 64 | asm __volatile__("movaps %xmm2, %xmm3"); 65 | asm __volatile__("movaps %xmm2, %xmm4"); 66 | asm __volatile__("movaps %xmm2, %xmm5"); 67 | asm __volatile__("movaps %xmm2, %xmm6"); 68 | asm __volatile__("movaps %xmm1, %xmm7"); 69 | asm __volatile__("xorps %xmm0, %xmm7"); 70 | do_fxsave (p); 71 | } 72 | 73 | int isFPLsbs ( int i ) 74 | { 75 | int q; 76 | q = 32; if (i == q || i == q+1) return 1; 77 | q = 48; if (i == q || i == q+1) return 1; 78 | q = 64; if (i == q || i == q+1) return 1; 79 | q = 80; if (i == q || i == q+1) return 1; 80 | q = 96; if (i == q || i == q+1) return 1; 81 | q = 112; if (i == q || i == q+1) return 1; 82 | q = 128; if (i == q || i == q+1) return 1; 83 | q = 144; if (i == q || i == q+1) return 1; 84 | return 0; 85 | } 86 | 87 | void show ( unsigned char* buf, int xx ) 88 | { 89 | int i; 90 | for (i = 0; i < 512; i++) { 91 | if ((i % 16) == 0) 92 | printf("%3d ", i); 93 | if (xx && isFPLsbs(i)) 94 | printf("xx "); 95 | else 96 | printf("%02x ", buf[i]); 97 | if (i > 0 && ((i % 16) == 15)) 98 | printf("\n"); 99 | } 100 | } 101 | 102 | 103 | int main ( int argc, char** argv ) 104 | { 105 | unsigned char* buf1 = memalign(16,512); 106 | unsigned char* buf2 = memalign(16,512); 107 | unsigned char* buf3 = memalign(16,512); 108 | int xx = argc > 1; 109 | printf("Re-run with any arg to suppress least-significant\n" 110 | " 16 bits of FP numbers\n"); 111 | memset(buf1, 0x55, 512); 112 | memset(buf2, 0x55, 512); 113 | memset(buf3, 0x55, 512); 114 | 115 | /* Load up x87/xmm state and dump it. */ 116 | do_setup_then_fxsave(buf1); 117 | printf("\nBEFORE\n"); 118 | show(buf1, xx); 119 | 120 | /* Zeroise x87/xmm state and dump it, to show that the 121 | regs have been cleared out. */ 122 | do_zeroise(); 123 | do_fxsave(buf2); 124 | printf("\nZEROED\n"); 125 | show(buf2, xx); 126 | 127 | /* Reload x87/xmm state from buf1 and dump it in buf3. */ 128 | do_fxrstor(buf1); 129 | do_fxsave(buf3); 130 | printf("\nRESTORED\n"); 131 | show(buf3, xx); 132 | 133 | free(buf1); free(buf2); free(buf3); 134 | 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /VEX/test/mxcsr.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | void mxcsr_default ( void ) 5 | { 6 | asm(" pushl $0x1F80 ; ldmxcsr (%esp) ; addl $4, %esp"); 7 | } 8 | 9 | void mxcsr_exns ( void ) 10 | { 11 | asm(" pushl $0x1F00 ; ldmxcsr (%esp) ; addl $4, %esp"); 12 | } 13 | 14 | /* PIII doesn't have DAZ, so this segfaults (!) on PIII. */a 15 | void mxcsr_daz ( void ) 16 | { 17 | asm(" pushl $0x1FC0 ; ldmxcsr (%esp) ; addl $4, %esp"); 18 | } 19 | 20 | void mxcsr_fz ( void ) 21 | { 22 | asm(" pushl $0x9F80 ; ldmxcsr (%esp) ; addl $4, %esp"); 23 | } 24 | 25 | 26 | int main ( void ) 27 | { 28 | printf("default\n"); 29 | mxcsr_default(); 30 | printf("\n"); 31 | 32 | printf("exns\n"); 33 | mxcsr_exns(); 34 | printf("\n"); 35 | 36 | printf("daz\n"); 37 | mxcsr_daz(); 38 | printf("\n"); 39 | 40 | printf("fz\n"); 41 | mxcsr_fz(); 42 | printf("\n"); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /VEX/test/rounderr.c: -------------------------------------------------------------------------------- 1 | 2 | /* peach (7400, altivec supported, 450MHz, gcc -O) 3 | m1 = 1.20000000000000018, exp = 1.19999999999999996 4 | m2 = 1.19999999999998885, exp = 1.19999999999999996 5 | */ 6 | 7 | /* peach (7400, altivec supported, 450MHz, gcc) 8 | m1 = 1.20000000000000018, exp = 1.19999999999999996 9 | m2 = 1.19999999999998885, exp = 1.19999999999999996 10 | */ 11 | 12 | /* phoenix, gcc -O 13 | m1 = 1.19999999999999996, exp = 1.19999999999999996 14 | m2 = 1.19999999999999996, exp = 1.19999999999999996 15 | */ 16 | 17 | /* phoenix, icc -O 18 | m1 = 1.19999999999999996, exp = 1.19999999999999996 19 | m2 = 1.19999999999999996, exp = 1.19999999999999996 20 | */ 21 | 22 | /* phoenix, gcc -O, iropt-level=2 23 | m1 = 1.20000000000000040, exp = 1.19999999999999996 24 | m2 = 1.19999999999999440, exp = 1.19999999999999996 25 | */ 26 | 27 | /* phoenix, gcc -O, iropt-level=1/0 28 | m1 = 1.20000000000000018, exp = 1.19999999999999996 29 | m2 = 1.19999999999998885, exp = 1.19999999999999996 30 | */ 31 | 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #define NNN 1000 38 | 39 | 40 | double 41 | my_mean1 (const double data[], size_t stride, const size_t size) 42 | { 43 | /* Compute the arithmetic mean of a dataset using the recurrence relation 44 | mean_(n) = mean(n-1) + (data[n] - mean(n-1))/(n+1) */ 45 | long double mean = 0; 46 | size_t i; 47 | 48 | for (i = 0; i < size; i++) 49 | { 50 | mean += (data[i * stride] - mean) / (i + 1); 51 | } 52 | return mean; 53 | } 54 | 55 | double 56 | my_mean2 (const double data[], size_t stride, const size_t size) 57 | { 58 | /* Compute the arithmetic mean of a dataset using the 59 | obvious scheme. */ 60 | int i; 61 | long double sum = 0; 62 | for (i = 0; i < size; i++) 63 | sum += data[i * stride]; 64 | return sum / (double)size; 65 | } 66 | 67 | 68 | int main (void) 69 | { 70 | int i; 71 | const size_t nacc2 = NNN+1; 72 | double numacc2[NNN+1] ; 73 | 74 | numacc2[0] = 1.2 ; 75 | 76 | for (i = 1 ; i < NNN; i += 2) 77 | numacc2[i] = 1.1 ; 78 | 79 | for (i = 1 ; i < NNN; i += 2) 80 | numacc2[i+1] = 1.3 ; 81 | 82 | #if 1 83 | asm __volatile__("fninit"); 84 | #endif 85 | 86 | { 87 | double m1 = my_mean1 (numacc2, 1, nacc2); 88 | double m2 = my_mean2 (numacc2, 1, nacc2); 89 | double expected_mean = 1.2; 90 | printf("m1 = %19.17f, exp = %19.17f\n", m1, expected_mean); 91 | printf("m2 = %19.17f, exp = %19.17f\n", m2, expected_mean); 92 | } 93 | 94 | return 0; 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /VEX/test/test-amd64-muldiv.h: -------------------------------------------------------------------------------- 1 | 2 | void glue(glue(test_, OP), b)(int64 op0, int64 op1) 3 | { 4 | int64 res, s1, s0, flags; 5 | s0 = op0; 6 | s1 = op1; 7 | res = s0; 8 | flags = 0; 9 | asm ("pushq %4\n\t" 10 | "popfq\n\t" 11 | stringify(OP)"b %b2\n\t" 12 | "pushfq\n\t" 13 | "popq %1\n\t" 14 | : "=a" (res), "=g" (flags) 15 | : "q" (s1), "0" (res), "1" (flags)); 16 | printf("%-10s A=%016llx B=%016llx R=%016llx CC=%04llx\n", 17 | stringify(OP) "b", s0, s1, res, flags & CC_MASK); 18 | } 19 | 20 | void glue(glue(test_, OP), w)(int64 op0h, int64 op0, int64 op1) 21 | { 22 | int64 res, s1, flags, resh; 23 | s1 = op1; 24 | resh = op0h; 25 | res = op0; 26 | flags = 0; 27 | asm ("pushq %5\n\t" 28 | "popfq\n\t" 29 | stringify(OP) "w %w3\n\t" 30 | "pushfq\n\t" 31 | "popq %1\n\t" 32 | : "=a" (res), "=g" (flags), "=d" (resh) 33 | : "q" (s1), "0" (res), "1" (flags), "2" (resh)); 34 | printf("%-10s AH=%016llx AL=%016llx B=%016llx RH=%016llx RL=%016llx CC=%04llx\n", 35 | stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK); 36 | } 37 | 38 | void glue(glue(test_, OP), l)(int64 op0h, int64 op0, int64 op1) 39 | { 40 | int64 res, s1, flags, resh; 41 | s1 = op1; 42 | resh = op0h; 43 | res = op0; 44 | flags = 0; 45 | asm ("pushq %5\n\t" 46 | "popfq\n\t" 47 | stringify(OP) "l %3\n\t" 48 | "pushfq\n\t" 49 | "popq %1\n\t" 50 | : "=a" (res), "=g" (flags), "=d" (resh) 51 | : "q" ((int)s1), "0" (res), "1" (flags), "2" (resh)); 52 | printf("%-10s AH=%016llx AL=%016llx B=%016llx RH=%016llx RL=%016llx CC=%04llx\n", 53 | stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK); 54 | } 55 | 56 | void glue(glue(test_, OP), q)(int64 op0h, int64 op0, int64 op1) 57 | { 58 | int64 res, s1, flags, resh; 59 | s1 = op1; 60 | resh = op0h; 61 | res = op0; 62 | flags = 0; 63 | asm ("pushq %5\n\t" 64 | "popfq\n\t" 65 | stringify(OP) "q %3\n\t" 66 | "pushfq\n\t" 67 | "popq %1\n\t" 68 | : "=a" (res), "=g" (flags), "=d" (resh) 69 | : "q" (s1), "0" (res), "1" (flags), "2" (resh)); 70 | printf("%-10s AH=%016llx AL=%016llx B=%016llx RH=%016llx RL=%016llx CC=%04llx\n", 71 | stringify(OP) "q", op0h, op0, s1, resh, res, flags & CC_MASK); 72 | } 73 | 74 | #undef OP 75 | -------------------------------------------------------------------------------- /VEX/test/test-amd64-shift.h: -------------------------------------------------------------------------------- 1 | 2 | #define exec_op glue(exec_, OP) 3 | #define exec_opq glue(glue(exec_, OP), q) 4 | #define exec_opl glue(glue(exec_, OP), l) 5 | #define exec_opw glue(glue(exec_, OP), w) 6 | #define exec_opb glue(glue(exec_, OP), b) 7 | 8 | #ifndef OP_SHIFTD 9 | 10 | #ifdef OP_NOBYTE 11 | #define EXECSHIFT(size, res, s1, s2, flags) \ 12 | asm ("pushq %4\n\t"\ 13 | "popfq\n\t"\ 14 | stringify(OP) size " %" size "2, %" size "0\n\t" \ 15 | "pushfq\n\t"\ 16 | "popq %1\n\t"\ 17 | : "=g" (res), "=g" (flags)\ 18 | : "r" (s1), "0" (res), "1" (flags)); 19 | #else 20 | #define EXECSHIFT(size, res, s1, s2, flags) \ 21 | asm ("pushq %4\n\t"\ 22 | "popfq\n\t"\ 23 | stringify(OP) size " %%cl, %" size "0\n\t" \ 24 | "pushfq\n\t"\ 25 | "popq %1\n\t"\ 26 | : "=q" (res), "=g" (flags)\ 27 | : "c" (s1), "0" (res), "1" (flags)); 28 | #endif 29 | 30 | void exec_opq(int64 s2, int64 s0, int64 s1, int64 iflags) 31 | { 32 | int64 res, flags; 33 | res = s0; 34 | flags = iflags; 35 | EXECSHIFT("q", res, s1, s2, flags); 36 | /* overflow is undefined if count != 1 */ 37 | if (s1 != 1) 38 | flags &= ~CC_O; 39 | printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 40 | stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK); 41 | } 42 | 43 | void exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags) 44 | { 45 | int64 res, flags; 46 | res = s0; 47 | flags = iflags; 48 | EXECSHIFT("", res, s1, s2, flags); 49 | /* overflow is undefined if count != 1 */ 50 | if (s1 != 1) 51 | flags &= ~CC_O; 52 | printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 53 | stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); 54 | } 55 | 56 | void exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags) 57 | { 58 | int64 res, flags; 59 | res = s0; 60 | flags = iflags; 61 | EXECSHIFT("w", res, s1, s2, flags); 62 | /* overflow is undefined if count != 1 */ 63 | if (s1 != 1) 64 | flags &= ~CC_O; 65 | printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 66 | stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); 67 | } 68 | 69 | #else 70 | #define EXECSHIFT(size, res, s1, s2, flags) \ 71 | asm ("pushq %4\n\t"\ 72 | "popfq\n\t"\ 73 | stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \ 74 | "pushfq\n\t"\ 75 | "popq %1\n\t"\ 76 | : "=g" (res), "=g" (flags)\ 77 | : "c" (s1), "0" (res), "1" (flags), "r" (s2)); 78 | 79 | void exec_opl(int64 s2, int64 s0, int64 s1, int64 iflags) 80 | { 81 | int64 res, flags; 82 | res = s0; 83 | flags = iflags; 84 | EXECSHIFT("", res, s1, s2, flags); 85 | /* overflow is undefined if count != 1 */ 86 | if (s1 != 1) 87 | flags &= ~CC_O; 88 | printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 89 | stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK); 90 | } 91 | 92 | void exec_opw(int64 s2, int64 s0, int64 s1, int64 iflags) 93 | { 94 | int64 res, flags; 95 | res = s0; 96 | flags = iflags; 97 | EXECSHIFT("w", res, s1, s2, flags); 98 | /* overflow is undefined if count != 1 */ 99 | if (s1 != 1) 100 | flags &= ~CC_O; 101 | printf("%-10s A=%016llx B=%016llx C=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 102 | stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK); 103 | } 104 | 105 | #endif 106 | 107 | #ifndef OP_NOBYTE 108 | void exec_opb(int64 s0, int64 s1, int64 iflags) 109 | { 110 | int64 res, flags; 111 | res = s0; 112 | flags = iflags; 113 | EXECSHIFT("b", res, s1, 0, flags); 114 | /* overflow is undefined if count != 1 */ 115 | if (s1 != 1) 116 | flags &= ~CC_O; 117 | printf("%-10s A=%016llx B=%016llx R=%016llx CCIN=%04llx CC=%04llx\n", 118 | stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); 119 | } 120 | #endif 121 | 122 | void exec_op(int64 s2, int64 s0, int64 s1) 123 | { 124 | int64 o,s,z,a,c,p,flags_in; 125 | for (o = 0; o < 2; o++) { 126 | for (s = 0; s < 2; s++) { 127 | for (z = 0; z < 2; z++) { 128 | for (a = 0; a < 2; a++) { 129 | for (c = 0; c < 2; c++) { 130 | for (p = 0; p < 2; p++) { 131 | 132 | flags_in = (o ? CC_O : 0) 133 | | (s ? CC_S : 0) 134 | | (z ? CC_Z : 0) 135 | | (a ? CC_A : 0) 136 | | (c ? CC_C : 0) 137 | | (p ? CC_P : 0); 138 | 139 | exec_opq(s2, s0, s1, flags_in); 140 | if (s1 <= 31) 141 | exec_opl(s2, s0, s1, flags_in); 142 | #ifdef OP_SHIFTD 143 | if (s1 <= 15) 144 | exec_opw(s2, s0, s1, flags_in); 145 | #else 146 | exec_opw(s2, s0, s1, flags_in); 147 | #endif 148 | #ifndef OP_NOBYTE 149 | exec_opb(s0, s1, flags_in); 150 | #endif 151 | #ifdef OP_CC 152 | exec_opq(s2, s0, s1, flags_in); 153 | exec_opl(s2, s0, s1, flags_in); 154 | exec_opw(s2, s0, s1, flags_in); 155 | exec_opb(s0, s1, flags_in); 156 | #endif 157 | 158 | }}}}}} 159 | 160 | } 161 | 162 | void glue(test_, OP)(void) 163 | { 164 | int64 i; 165 | for(i = 0; i < 64; i++) 166 | exec_op(0x3141592721ad3d34, 0x2718284612345678, i); 167 | for(i = 0; i < 64; i++) 168 | exec_op(0x31415927813f3421, 0x2718284682345678, i); 169 | } 170 | 171 | void *glue(_test_, OP) __init_call = glue(test_, OP); 172 | 173 | #undef OP 174 | #undef OP_CC 175 | #undef OP_SHIFTD 176 | #undef OP_NOBYTE 177 | #undef EXECSHIFT 178 | 179 | -------------------------------------------------------------------------------- /VEX/test/test-i386-muldiv.h: -------------------------------------------------------------------------------- 1 | 2 | void glue(glue(test_, OP), b)(int op0, int op1) 3 | { 4 | int res, s1, s0, flags; 5 | s0 = op0; 6 | s1 = op1; 7 | res = s0; 8 | flags = 0; 9 | asm ("push %4\n\t" 10 | "popf\n\t" 11 | stringify(OP)"b %b2\n\t" 12 | "pushf\n\t" 13 | "popl %1\n\t" 14 | : "=a" (res), "=g" (flags) 15 | : "q" (s1), "0" (res), "1" (flags)); 16 | printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", 17 | stringify(OP) "b", s0, s1, res, flags & CC_MASK); 18 | } 19 | 20 | void glue(glue(test_, OP), w)(int op0h, int op0, int op1) 21 | { 22 | int res, s1, flags, resh; 23 | s1 = op1; 24 | resh = op0h; 25 | res = op0; 26 | flags = 0; 27 | asm ("push %5\n\t" 28 | "popf\n\t" 29 | stringify(OP) "w %w3\n\t" 30 | "pushf\n\t" 31 | "popl %1\n\t" 32 | : "=a" (res), "=g" (flags), "=d" (resh) 33 | : "q" (s1), "0" (res), "1" (flags), "2" (resh)); 34 | printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n", 35 | stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK); 36 | } 37 | 38 | void glue(glue(test_, OP), l)(int op0h, int op0, int op1) 39 | { 40 | int res, s1, flags, resh; 41 | s1 = op1; 42 | resh = op0h; 43 | res = op0; 44 | flags = 0; 45 | asm ("push %5\n\t" 46 | "popf\n\t" 47 | stringify(OP) "l %3\n\t" 48 | "pushf\n\t" 49 | "popl %1\n\t" 50 | : "=a" (res), "=g" (flags), "=d" (resh) 51 | : "q" (s1), "0" (res), "1" (flags), "2" (resh)); 52 | printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n", 53 | stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK); 54 | } 55 | 56 | #undef OP 57 | -------------------------------------------------------------------------------- /VEX/test/test-i386-shift.h: -------------------------------------------------------------------------------- 1 | 2 | #define exec_op glue(exec_, OP) 3 | #define exec_opl glue(glue(exec_, OP), l) 4 | #define exec_opw glue(glue(exec_, OP), w) 5 | #define exec_opb glue(glue(exec_, OP), b) 6 | 7 | #ifndef OP_SHIFTD 8 | 9 | #ifdef OP_NOBYTE 10 | #define EXECSHIFT(size, res, s1, s2, flags) \ 11 | asm ("push %4\n\t"\ 12 | "popf\n\t"\ 13 | stringify(OP) size " %" size "2, %" size "0\n\t" \ 14 | "pushf\n\t"\ 15 | "popl %1\n\t"\ 16 | : "=g" (res), "=g" (flags)\ 17 | : "r" (s1), "0" (res), "1" (flags)); 18 | #else 19 | #define EXECSHIFT(size, res, s1, s2, flags) \ 20 | asm ("push %4\n\t"\ 21 | "popf\n\t"\ 22 | stringify(OP) size " %%cl, %" size "0\n\t" \ 23 | "pushf\n\t"\ 24 | "popl %1\n\t"\ 25 | : "=q" (res), "=g" (flags)\ 26 | : "c" (s1), "0" (res), "1" (flags)); 27 | #endif 28 | 29 | void exec_opl(int s2, int s0, int s1, int iflags) 30 | { 31 | int res, flags; 32 | res = s0; 33 | flags = iflags; 34 | EXECSHIFT("", res, s1, s2, flags); 35 | /* overflow is undefined if count != 1 */ 36 | if (s1 != 1) 37 | flags &= ~CC_O; 38 | printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", 39 | stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); 40 | } 41 | 42 | void exec_opw(int s2, int s0, int s1, int iflags) 43 | { 44 | int res, flags; 45 | res = s0; 46 | flags = iflags; 47 | EXECSHIFT("w", res, s1, s2, flags); 48 | /* overflow is undefined if count != 1 */ 49 | if (s1 != 1) 50 | flags &= ~CC_O; 51 | printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", 52 | stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); 53 | } 54 | 55 | #else 56 | #define EXECSHIFT(size, res, s1, s2, flags) \ 57 | asm ("push %4\n\t"\ 58 | "popf\n\t"\ 59 | stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \ 60 | "pushf\n\t"\ 61 | "popl %1\n\t"\ 62 | : "=g" (res), "=g" (flags)\ 63 | : "c" (s1), "0" (res), "1" (flags), "r" (s2)); 64 | 65 | void exec_opl(int s2, int s0, int s1, int iflags) 66 | { 67 | int res, flags; 68 | res = s0; 69 | flags = iflags; 70 | EXECSHIFT("", res, s1, s2, flags); 71 | /* overflow is undefined if count != 1 */ 72 | if (s1 != 1) 73 | flags &= ~CC_O; 74 | printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n", 75 | stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK); 76 | } 77 | 78 | void exec_opw(int s2, int s0, int s1, int iflags) 79 | { 80 | int res, flags; 81 | res = s0; 82 | flags = iflags; 83 | EXECSHIFT("w", res, s1, s2, flags); 84 | /* overflow is undefined if count != 1 */ 85 | if (s1 != 1) 86 | flags &= ~CC_O; 87 | printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n", 88 | stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK); 89 | } 90 | 91 | #endif 92 | 93 | #ifndef OP_NOBYTE 94 | void exec_opb(int s0, int s1, int iflags) 95 | { 96 | int res, flags; 97 | res = s0; 98 | flags = iflags; 99 | EXECSHIFT("b", res, s1, 0, flags); 100 | /* overflow is undefined if count != 1 */ 101 | if (s1 != 1) 102 | flags &= ~CC_O; 103 | printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n", 104 | stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); 105 | } 106 | #endif 107 | 108 | void exec_op(int s2, int s0, int s1) 109 | { 110 | int o,s,z,a,c,p,flags_in; 111 | for (o = 0; o < 2; o++) { 112 | for (s = 0; s < 2; s++) { 113 | for (z = 0; z < 2; z++) { 114 | for (a = 0; a < 2; a++) { 115 | for (c = 0; c < 2; c++) { 116 | for (p = 0; p < 2; p++) { 117 | 118 | flags_in = (o ? CC_O : 0) 119 | | (s ? CC_S : 0) 120 | | (z ? CC_Z : 0) 121 | | (a ? CC_A : 0) 122 | | (c ? CC_C : 0) 123 | | (p ? CC_P : 0); 124 | 125 | exec_opl(s2, s0, s1, flags_in); 126 | #ifdef OP_SHIFTD 127 | if (s1 <= 15) 128 | exec_opw(s2, s0, s1, flags_in); 129 | #else 130 | exec_opw(s2, s0, s1, flags_in); 131 | #endif 132 | #ifndef OP_NOBYTE 133 | exec_opb(s0, s1, flags_in); 134 | #endif 135 | #ifdef OP_CC 136 | exec_opl(s2, s0, s1, flags_in); 137 | exec_opw(s2, s0, s1, flags_in); 138 | exec_opb(s0, s1, flags_in); 139 | #endif 140 | 141 | }}}}}} 142 | 143 | } 144 | 145 | void glue(test_, OP)(void) 146 | { 147 | int i; 148 | for(i = 0; i < 32; i++) 149 | exec_op(0x21ad3d34, 0x12345678, i); 150 | for(i = 0; i < 32; i++) 151 | exec_op(0x813f3421, 0x82345678, i); 152 | } 153 | 154 | void *glue(_test_, OP) __init_call = glue(test_, OP); 155 | 156 | #undef OP 157 | #undef OP_CC 158 | #undef OP_SHIFTD 159 | #undef OP_NOBYTE 160 | #undef EXECSHIFT 161 | 162 | -------------------------------------------------------------------------------- /VEX/test/x87fxam.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | double d; 6 | int i; 7 | 8 | extern void do_fxam ( void ); 9 | 10 | asm( 11 | "\n" 12 | "do_fxam:\n" 13 | "\txorl %eax,%eax\n" 14 | "\tfld d\n" 15 | "\tfxam\n" 16 | "\tfnstsw %ax\n" 17 | "\tffree %st(0)\n" 18 | "\tmovl %eax, i\n" 19 | "\tret\n" 20 | ); 21 | 22 | 23 | double inf ( void ) { return 1.0 / 0.0; } 24 | double nAn ( void ) { return 0.0 / 0.0; } 25 | double den ( void ) { return 9.1e-220 / 1e100; } 26 | 27 | /* Try positive and negative variants of: zero, infinity, 28 | nAn, and denorm */ 29 | 30 | int main ( void ) 31 | { 32 | d = 0.0; do_fxam(); printf("0x%4x: %f\n", i, d ); 33 | d = -0.0; do_fxam(); printf("0x%4x: %f\n", i, d ); 34 | 35 | d = inf(); do_fxam(); printf("0x%4x: %f\n", i, d ); 36 | d = -inf(); do_fxam(); printf("0x%4x: %f\n", i, d ); 37 | 38 | d = nAn(); do_fxam(); printf("0x%4x: %f\n", i, d ); 39 | d = -nAn(); do_fxam(); printf("0x%4x: %f\n", i, d ); 40 | 41 | d = den(); do_fxam(); printf("0x%4x: %f\n", i, d ); 42 | d = -den(); do_fxam(); printf("0x%4x: %f\n", i, d ); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /VEX/test/x87tst.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | double d; 6 | int i; 7 | 8 | extern void do_tst ( void ); 9 | 10 | asm( 11 | "\n" 12 | "do_tst:\n" 13 | "\txorl %eax,%eax\n" 14 | "\tfld d\n" 15 | "\tftst\n" 16 | "\tfnstsw %ax\n" 17 | "\tmovl %eax, i\n" 18 | "\tret\n" 19 | ); 20 | 21 | int main ( void ) 22 | { 23 | d = -1.23; do_tst(); printf("%f -> 0x%x\n", d, i ); 24 | d = 0.0; do_tst(); printf("%f -> 0x%x\n", d, i ); 25 | d = 9.87; do_tst(); printf("%f -> 0x%x\n", d, i ); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /VEX/unused/arena.h: -------------------------------------------------------------------------------- 1 | 2 | /* This is a modified version of the file "arena.h" from 3 | "C Interfaces and Implementations", by David R. Hanson. 4 | The license is below. 5 | */ 6 | /* 7 | 8 | The author of this software is David R. Hanson. 9 | 10 | Copyright (c) 1994,1995,1996,1997 by David R. Hanson. All Rights Reserved. 11 | 12 | Permission to use, copy, modify, and distribute this software for any 13 | purpose, subject to the provisions described below, without fee is 14 | hereby granted, provided that this entire notice is included in all 15 | copies of any software that is or includes a copy or modification of 16 | this software and in all copies of the supporting documentation for 17 | such software. 18 | 19 | THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 20 | WARRANTY. IN PARTICULAR, THE AUTHOR DOES MAKE ANY REPRESENTATION OR 21 | WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS SOFTWARE OR 22 | ITS FITNESS FOR ANY PARTICULAR PURPOSE. 23 | 24 | David Hanson / drh@microsoft.com / http://www.research.microsoft.com/~drh/ 25 | $Id: CPYRIGHT,v 1.2 1997/11/04 22:31:40 drh Exp $ 26 | */ 27 | 28 | /* $Id: H:/drh/idioms/book/RCS/arena.doc,v 1.10 1997/02/21 19:45:19 drh Exp $ */ 29 | 30 | #ifndef _CII_ARENA_H 31 | #define _CII_ARENA_H 32 | 33 | //#include "except.h" 34 | #define T Arena_T 35 | typedef struct T *T; 36 | //extern const Except_T Arena_NewFailed; 37 | //extern const Except_T Arena_Failed; 38 | extern T Arena_new (void); 39 | extern void Arena_dispose(T *ap); 40 | extern void *Arena_alloc (T arena, long nbytes, 41 | const char *file, int line); 42 | extern void *Arena_calloc(T arena, long count, 43 | long nbytes, const char *file, int line); 44 | extern void Arena_free (T arena); 45 | #undef T 46 | 47 | #endif /* ndef _CII_ARENA_H */ 48 | -------------------------------------------------------------------------------- /VEX/unused/dispatch.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------*/ 3 | /*--- begin dispatch.c ---*/ 4 | /*---------------------------------------------------------------*/ 5 | 6 | #include "basictypes.h" 7 | 8 | 9 | /* --------------------------------------------------------- */ 10 | /* TRANSLATION TABLE/CACHE */ 11 | /* --------------------------------------------------------- */ 12 | 13 | static 14 | char* find_translation ( char* orig ) 15 | { 16 | int i; 17 | for (i = 0; i < n_transtab_used; i++) 18 | if (transtab[i].orig == orig) 19 | return transtab[i].trans; 20 | return NULL; 21 | } 22 | 23 | 24 | #define N_TT_ENTRIES 1000 25 | 26 | typedef 27 | struct { 28 | char* orig; 29 | int orig_size; 30 | char* trans; 31 | int trans_size; 32 | } 33 | TTEntry; 34 | 35 | int n_transtab_used = 0; 36 | TTEntry transtab[N_TT_ENTRIES]; 37 | 38 | 39 | /* Call here to add a translation to the trans cache. 40 | Supplied translation is in mallocville. add_translation should 41 | copy it out as the caller will free it on return. */ 42 | 43 | /* EXPORTED */ 44 | void add_translation ( char* orig, int orig_size, char* trans, int trans_size ) 45 | { 46 | int i; 47 | assert(n_transtab_used < N_TT_ENTRIES); 48 | transtab[n_transtab_used].orig = orig; 49 | transtab[n_transtab_used].orig_size = orig_size; 50 | transtab[n_transtab_used].trans_size = trans_size; 51 | 52 | transtab[n_transtab_used].trans = malloc(trans_size); 53 | assert(transtab[n_transtab_used].trans != NULL); 54 | for (i = 0; i < trans_size; i++) 55 | transtab[n_transtab_used].trans[i] = trans[i]; 56 | 57 | #ifdef arm_TARGET_ARCH 58 | arm_notify_new_code(transtab[n_transtab_used].trans, trans_size); 59 | #endif 60 | 61 | n_transtab_used++; 62 | } 63 | 64 | /* Run the simulated machine for a while. Returns when a new BB needs 65 | to be translated, and returns its address. Returns NULL when we 66 | want to stop. */ 67 | 68 | /* EXPORTED */ 69 | char* run_machine ( void ) 70 | { 71 | char* nextpc_orig; 72 | char* nextpc_trans; 73 | while (1) { 74 | nextpc_orig = (char*)(regs_arm[REG_PC]); 75 | if (nextpc_orig == stop_at) 76 | return NULL; 77 | nextpc_trans = find_translation(nextpc_orig); 78 | if (nextpc_trans == NULL) 79 | return nextpc_orig; 80 | run_translation(nextpc_trans, (char*) ®s_arm[0] ); 81 | } 82 | } 83 | 84 | 85 | /* HOW TO USE: 86 | 87 | for a main fn :: void main ( void ) 88 | 89 | * load .o's, link, etc 90 | 91 | * call initialise_machine with & main 92 | 93 | * call run_machine repeatedly. If it returns NULL, stop. Else 94 | make a translation of the returned address, pass it to 95 | add_translation, and resume running by calling run_machine. 96 | 97 | */ 98 | -------------------------------------------------------------------------------- /VEX/useful/Makefile-vex: -------------------------------------------------------------------------------- 1 | # Crude makefile to build the "vex" executable from test_main.c 2 | 3 | vex: test_main.c test_main.h ../pub/*.h ../priv/*.c ../priv/*.h 4 | (cd ..; make -f Makefile-gcc) 5 | cc -I../pub -o vex test_main.c ../libvex.a 6 | 7 | clean: 8 | rm -f vex ../priv/*.o 9 | -------------------------------------------------------------------------------- /VEX/useful/cpuid.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | typedef unsigned int UInt; 5 | typedef unsigned long long int ULong; 6 | 7 | void cpuid ( UInt* eax, UInt* ebx, UInt* ecx, UInt* edx, 8 | UInt index, UInt ecx_in ) 9 | { 10 | UInt a,b,c,d; 11 | asm volatile ("cpuid" 12 | : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 13 | : "0" (index), "2"(ecx_in) ); 14 | *eax = a; *ebx = b; *ecx = c; *edx = d; 15 | printf("%08x %08x -> %08x %08x %08x %08x\n", 16 | index,ecx_in, a,b,c,d ); 17 | } 18 | 19 | int main ( void ) 20 | { 21 | UInt eax, ebx, ecx, edx; 22 | UInt maxidx, maxextidx, i,ecx_in; 23 | 24 | printf("\n"); 25 | cpuid(&eax,&ebx,&ecx,&edx, 0,0); 26 | maxidx = eax; 27 | for (i = 1; i <= maxidx +5; i++) { 28 | 29 | UInt subleaf = 0; 30 | 31 | if (i == 4) subleaf = 10; 32 | if (i == 7) subleaf = 10; 33 | if (i == 0xB) subleaf = 10; 34 | if (i == 0xD) subleaf = 10; 35 | 36 | if (subleaf > 0) printf("\n"); 37 | 38 | cpuid(&eax,&ebx,&ecx,&edx, i,0); 39 | 40 | for (ecx_in = 1; ecx_in < subleaf; ecx_in++) { 41 | cpuid(&eax,&ebx,&ecx,&edx, i,ecx_in); 42 | } 43 | 44 | if (subleaf > 0) printf("\n"); 45 | 46 | } 47 | 48 | printf("\n"); 49 | 50 | cpuid(&eax,&ebx,&ecx,&edx, 0x80000000,0); 51 | maxextidx = eax; 52 | for (i = 0x80000001; i <= maxextidx +5; i++) { 53 | cpuid(&eax,&ebx,&ecx,&edx, i,0); 54 | } 55 | 56 | printf("invalid\n"); 57 | cpuid(&eax,&ebx,&ecx,&edx, 1234,0); 58 | cpuid(&eax,&ebx,&ecx,&edx, 0x800004d3,0); 59 | 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /VEX/useful/fpround.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main ( void ) 5 | { 6 | double d = 0.0; 7 | int i; 8 | for (i = 0; i < 30; i++) { 9 | printf("i = %d, d = %f, (int)d = %d\n", i, d, (int)d); 10 | d += 0.11; 11 | } 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /VEX/useful/fspill.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | double qq ( void ) 5 | {int i; 6 | long double a = 0.0, b = 0.0, c = 0.0, d = 0.0, e = 0.0, f = 0.0, g = 0.0, h = 0.0; 7 | for (i = 0; i < 10; i++) { 8 | a += 1.1; b += 1.2; c += 1.3; d += 1.4; e += 1.5; f += 1.6; 9 | g += 1.7; h += 1.8001; 10 | } 11 | return a+b+c+d+e+f+g+h; 12 | } 13 | 14 | int main ( void ) 15 | { 16 | double r = qq(); 17 | printf("answer is %f %d\n", r, (int)r ); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /VEX/useful/gradual_underflow.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | int main ( void ) 5 | { 6 | double d = 7.25063790881233303e-303; 7 | int i; 8 | 9 | for (i = 0; i < 26; i++) { 10 | printf("%.16e\n", d); 11 | d *= 0.1012198489248992489422; 12 | } 13 | return 0; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /VEX/useful/show_fp_state.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | 6 | /* ------------------------------------------------- */ 7 | 8 | typedef unsigned char UChar; 9 | typedef unsigned short UShort; 10 | typedef unsigned int UInt; 11 | typedef unsigned long long int ULong; 12 | 13 | typedef signed char Char; 14 | typedef short Short; 15 | typedef int Int; 16 | typedef long long int Long; 17 | 18 | typedef 19 | struct { 20 | UShort env[14]; 21 | UChar reg[80]; 22 | } 23 | Fpu_State; 24 | 25 | /* Offsets, in 16-bit ints, into the FPU environment (env) area. */ 26 | #define FP_ENV_CTRL 0 27 | #define FP_ENV_STAT 2 28 | #define FP_ENV_TAG 4 29 | #define FP_ENV_IP 6 /* and 7 */ 30 | #define FP_ENV_CS 8 31 | #define FP_ENV_OPOFF 10 /* and 11 */ 32 | #define FP_ENV_OPSEL 12 33 | #define FP_REG(ii) (10*(7-(ii))) 34 | 35 | /* Bitfield offsets for exceptions in the FPU status and control words. */ 36 | #define FP_E_INVAL 0 37 | #define FP_E_DENOR 1 38 | #define FP_E_DIVZ 2 39 | #define FP_E_OVERF 3 40 | #define FP_E_UNDER 4 41 | #define FP_E_LOS 5 42 | 43 | /* More bitfield offsets, but for the status word only. */ 44 | #define FP_E_STACKF 6 45 | #define FP_E_SUMMARY 7 46 | #define FP_F_C0 8 47 | #define FP_F_C1 9 48 | #define FP_F_C2 10 49 | #define FP_F_C3 14 50 | /* top-of-stack ptr is bits 13,12,11 of the word */ 51 | #define FP_F_TOS_LO 11 52 | #define FP_F_TOS_HI 13 53 | 54 | /* Register tags. */ 55 | #define FP_TAG_VALID 0 56 | #define FP_TAG_ZERO 1 57 | #define FP_TAG_SPEC 2 58 | #define FP_TAG_EMPTY 3 59 | 60 | char* fp_tag_names[4] 61 | = { "Valid", "Zero", "Spec", "Empty" }; 62 | 63 | char* fp_exception_names[6] 64 | = { "INVAL", "DENOR", "DIVZ", "OVERF", "UNDERF", "LOS" }; 65 | 66 | Fpu_State m_fpu_state; 67 | 68 | 69 | 70 | UInt fp_get_tos ( void ) 71 | { 72 | return (m_fpu_state.env[FP_ENV_STAT] >> FP_F_TOS_LO) & 7; 73 | } 74 | 75 | UInt fp_get_tag ( UInt regno ) 76 | { 77 | assert(!(regno < 0 || regno > 7)); 78 | return (m_fpu_state.env[FP_ENV_TAG] >> (2*regno)) & 3; 79 | } 80 | 81 | UInt fp_get_statusword_flag ( UInt flagno ) 82 | { 83 | assert(!(flagno < 0 || flagno > 15)); 84 | return (m_fpu_state.env[FP_ENV_STAT] >> flagno) & 0x1; 85 | } 86 | 87 | UInt fp_get_controlword_flag ( UInt flagno ) 88 | { 89 | assert(!(flagno < 0 || flagno > 15)); 90 | return (m_fpu_state.env[FP_ENV_CTRL] >> flagno) & 0x1; 91 | } 92 | 93 | static 94 | void printFpuState ( void ) 95 | { 96 | Int i, j, k; 97 | assert(sizeof(Fpu_State)==108); 98 | for (i = 7; i >= 0; i--) { 99 | printf ( " %s fpreg%d: 0x", 100 | (UInt)i == fp_get_tos() ? "**" : " ", i ); 101 | for (k = 0, j = FP_REG(i)+9; k < 10; k++,j--) 102 | printf ( "%02x", (UInt)m_fpu_state.reg[j]); 103 | printf ( " %5s ", fp_tag_names[fp_get_tag(i)] ); 104 | printf("\n"); 105 | //printf ( "%20.16e\n", fp_get_reg(i) ); 106 | } 107 | printf(" fctrl: 0x%04x masked: ", 108 | (UInt)m_fpu_state.env[FP_ENV_CTRL] ); 109 | for (i = FP_E_INVAL; i <= FP_E_LOS; i++) 110 | if (fp_get_controlword_flag(i)) 111 | printf ( "%s ", fp_exception_names[i] ); 112 | printf ( "\n" ); 113 | 114 | printf(" fstat: 0x%04x except:", 115 | (UInt)m_fpu_state.env[FP_ENV_STAT] ); 116 | for (i = FP_E_INVAL; i <= FP_E_LOS; i++) 117 | if (fp_get_statusword_flag(i)) 118 | printf ( "%s ", fp_exception_names[i] ); 119 | printf ( " top: %d ", fp_get_tos() ); 120 | printf ( "c3210: %d%d%d%d", 121 | fp_get_statusword_flag(FP_F_C3), 122 | fp_get_statusword_flag(FP_F_C2), 123 | fp_get_statusword_flag(FP_F_C1), 124 | fp_get_statusword_flag(FP_F_C0) ); 125 | printf ( " STACKF: %d\n", fp_get_statusword_flag(FP_E_STACKF) ); 126 | 127 | printf(" ftag: 0x%04x ", (UInt)m_fpu_state.env[FP_ENV_TAG] ); 128 | for (i = 7; i >= 0; i--) 129 | printf ( "%d:%s ", i, fp_tag_names[fp_get_tag(i)] ); 130 | printf("\n"); 131 | 132 | printf(" fip: 0x%08x\n", 133 | (((UInt)m_fpu_state.env[FP_ENV_IP+1]) << 16) | 134 | ((UInt)m_fpu_state.env[FP_ENV_IP]) ); 135 | printf(" fcs: 0x%04x\n", 136 | ((UInt)m_fpu_state.env[FP_ENV_CS]) ); 137 | printf(" fopoff: 0x%08x\n", 138 | (((UInt)m_fpu_state.env[FP_ENV_OPOFF+1]) << 16) | 139 | ((UInt)m_fpu_state.env[FP_ENV_OPOFF]) ); 140 | printf(" fopsel: 0x%04x\n", 141 | ((UInt)m_fpu_state.env[FP_ENV_OPSEL]) ); 142 | } 143 | 144 | 145 | /* ------------------------------------------------- */ 146 | 147 | 148 | /* Initialise the FPU, dump its state, and print it. */ 149 | 150 | 151 | void show ( unsigned char* st ) 152 | { 153 | int i; 154 | for (i = 0; i < 28; i++) { 155 | printf("%02x ", st[i]); 156 | if (i > 0 && ((i & 3) == 3)) printf("\n"); 157 | } 158 | for (i = 0; i < 80; i++) { 159 | printf("%02x ", st[i+28]); 160 | if (i > 0 && ((i % 10) == 9)) printf("\n"); 161 | } 162 | printf("\n"); 163 | } 164 | 165 | int main ( void ) 166 | { 167 | Fpu_State* st = &m_fpu_state; 168 | assert(sizeof(m_fpu_state) == 108); 169 | asm volatile ("finit ; fnsave %0" 170 | : "=m" (m_fpu_state) 171 | : 172 | : "memory" ); 173 | printFpuState(); 174 | printf("\n\n"); 175 | 176 | asm volatile ("fildl 0(%%esp) ; pushl $17 ; fildl 0(%%esp) ; addl $4, %%esp ; fnsave %0" 177 | : "=m" (m_fpu_state) 178 | : 179 | : "memory" ); 180 | printFpuState(); 181 | printf("\n"); 182 | show(st); 183 | return 0; 184 | } 185 | -------------------------------------------------------------------------------- /VEX/useful/test_main.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copy this file (test_main.h.in) to test_main.h, and edit */ 3 | 4 | /* DEBUG RUN, ON V */ 5 | #if 1 6 | #define TEST_N_ITERS 1 7 | #define TEST_N_BBS 1 8 | #define TEST_FLAGS (1<<7)|(0<<6)|(1<<3)|(0<<2)|(0<<1)|(0<<0) 9 | #endif 10 | 11 | /* CHECKING RUN, ON V */ 12 | #if 0 13 | #define TEST_N_ITERS 1 14 | #define TEST_N_BBS 100000 15 | #define TEST_FLAGS 0 16 | #endif 17 | 18 | /* PROFILING RUN, NATIVE */ 19 | #if 0 20 | #define TEST_N_ITERS 100 21 | #define TEST_N_BBS 1000 22 | #define TEST_FLAGS 0 23 | #endif 24 | 25 | /* PROFILING RUN, REDUCED WORKLOAD */ 26 | #if 0 27 | #define TEST_N_ITERS 3 28 | #define TEST_N_BBS 1000 29 | #define TEST_FLAGS 0 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /VEX/useful/test_main.h.base: -------------------------------------------------------------------------------- 1 | 2 | /* Copy this file (test_main.h.in) to test_main.h, and edit */ 3 | 4 | /* DEBUG RUN, ON V */ 5 | #if 1 6 | #define TEST_N_ITERS 1 7 | #define TEST_N_BBS 1 8 | #define TEST_FLAGS (1<<7) 9 | #endif 10 | 11 | /* CHECKING RUN, ON V */ 12 | #if 0 13 | #define TEST_N_ITERS 1 14 | #define TEST_N_BBS 100000 15 | #define TEST_FLAGS 0 16 | #endif 17 | 18 | /* PROFILING RUN, NATIVE */ 19 | #if 0 20 | #define TEST_N_ITERS 100 21 | #define TEST_N_BBS 1000 22 | #define TEST_FLAGS 0 23 | #endif 24 | 25 | /* PROFILING RUN, REDUCED WORKLOAD */ 26 | #if 0 27 | #define TEST_N_ITERS 3 28 | #define TEST_N_BBS 1000 29 | #define TEST_FLAGS 0 30 | #endif 31 | 32 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | aclocal 2 | autoconf 3 | autoheader 4 | automake --add-missing --copy 5 | -------------------------------------------------------------------------------- /capstone/Makefile: -------------------------------------------------------------------------------- 1 | 2 | capstone/libcapstone.a: 3 | 4 | [ -d capstone ] || git clone https://github.com/Cr4sh/capstone.git 5 | cp config.mk capstone 6 | cd capstone && make 7 | 8 | all: capstone/libcapstone.a 9 | 10 | clean: 11 | 12 | cd capstone && make clean 13 | 14 | install: 15 | 16 | -------------------------------------------------------------------------------- /capstone/config.mk: -------------------------------------------------------------------------------- 1 | # This file contains all customized compile options for Capstone. 2 | # Modify it before building step. Consult docs/README for details. 3 | 4 | ################################################################################ 5 | # Specify which archs you want to compile in. By default, we build all archs. 6 | 7 | CAPSTONE_ARCHS ?= arm x86 8 | 9 | 10 | ################################################################################ 11 | # Comment out the line below ('CAPSTONE_USE_SYS_DYN_MEM = yes'), or change it to 12 | # 'CAPSTONE_USE_SYS_DYN_MEM = no' if do NOT use malloc/calloc/realloc/free/ 13 | # vsnprintf() provided by system for internal dynamic memory management. 14 | # 15 | # NOTE: in that case, specify your own malloc/calloc/realloc/free/vsnprintf() 16 | # functions in your program via API cs_option(), using CS_OPT_MEM option type. 17 | 18 | CAPSTONE_USE_SYS_DYN_MEM ?= yes 19 | 20 | 21 | ################################################################################ 22 | # Change 'CAPSTONE_DIET = no' to 'CAPSTONE_DIET = yes' to make the library 23 | # more compact: use less memory & smaller in binary size. 24 | # This setup will remove the @mnemonic & @op_str data, plus semantic information 25 | # such as @regs_read/write & @group. The amount of binary size reduced is 26 | # up to 50% in some individual archs. 27 | # 28 | # NOTE: we still keep all those related fileds @mnemonic, @op_str, @regs_read, 29 | # @regs_write, @groups, etc in fields in cs_insn structure regardless, but they 30 | # will not be updated (i.e empty), thus become irrelevant. 31 | 32 | CAPSTONE_DIET ?= no 33 | 34 | 35 | ################################################################################ 36 | # Change 'CAPSTONE_X86_REDUCE = no' to 'CAPSTONE_X86_REDUCE = yes' to remove 37 | # non-critical instruction sets of X86, making the binary size smaller by ~60%. 38 | # This is desired in special cases, such as OS kernel, where these kind of 39 | # instructions are not used. 40 | # 41 | # The list of instruction sets to be removed includes: 42 | # - Floating Point Unit (FPU) 43 | # - MultiMedia eXtension (MMX) 44 | # - Streaming SIMD Extensions (SSE) 45 | # - 3DNow 46 | # - Advanced Vector Extensions (AVX) 47 | # - Fused Multiply Add Operations (FMA) 48 | # - eXtended Operations (XOP) 49 | # - Transactional Synchronization Extensions (TSX) 50 | # 51 | # Due to this removal, the related instructions are nolonger supported. 52 | # 53 | # By default, Capstone is compiled with 'CAPSTONE_X86_REDUCE = no', 54 | # thus supports complete X86 instructions. 55 | 56 | CAPSTONE_X86_REDUCE ?= no 57 | 58 | ################################################################################ 59 | # Change 'CAPSTONE_X86_ATT_DISABLE = no' to 'CAPSTONE_X86_ATT_DISABLE = yes' to 60 | # disable AT&T syntax on x86 to reduce library size. 61 | 62 | CAPSTONE_X86_ATT_DISABLE ?= yes 63 | 64 | ################################################################################ 65 | # Change 'CAPSTONE_STATIC = yes' to 'CAPSTONE_STATIC = no' to avoid building 66 | # a static library. 67 | 68 | CAPSTONE_STATIC ?= yes 69 | 70 | 71 | ################################################################################ 72 | # Change 'CAPSTONE_SHARED = yes' to 'CAPSTONE_SHARED = no' to avoid building 73 | # a shared library. 74 | 75 | CAPSTONE_SHARED ?= no 76 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ(2.59) 5 | AC_INIT(OpenREIL, 0.1, cr4sh0@gmail.com) 6 | AC_CONFIG_SRCDIR([libasmir/src/irtoir.cpp]) 7 | AC_CONFIG_HEADER([libasmir/config.h]) 8 | 9 | AM_INIT_AUTOMAKE 10 | 11 | # Checks for programs. 12 | AC_PROG_CXX 13 | AC_PROG_CC 14 | AC_PROG_MAKE_SET 15 | AC_PROG_RANLIB 16 | 17 | AM_PATH_PYTHON(, , AC_MSG_ERROR([Python not found])) 18 | 19 | AC_CHECK_PROG(CYTHON_FOUND, cython, yes) 20 | if test x"$CYTHON_FOUND" != x"yes" ; then 21 | AC_MSG_ERROR([Cython not found]) 22 | fi 23 | 24 | # Python library 25 | AC_CHECK_LIB([python$PYTHON_VERSION], [Py_Initialize], , AC_MSG_ERROR([Python library not found])) 26 | 27 | # Add -DAMD64 when needed 28 | if test "$(uname -m)" == "x86_64"; 29 | then export CFLAGS="$CFLAGS -DAMD64"; 30 | fi 31 | 32 | AC_SUBST(XED_DIR) 33 | XED_DIR=`pwd`/'xed2-ia32' 34 | 35 | AC_SUBST(CAPSTONE_DIR) 36 | CAPSTONE_DIR=`pwd`/'capstone/capstone' 37 | 38 | AC_SUBST(DISASM_NAME) 39 | DISASM_NAME='capstone' 40 | 41 | AC_SUBST(DISASM_INC) 42 | DISASM_INC='${CAPSTONE_DIR}/include' 43 | 44 | # OS-specific stuff 45 | AC_SUBST(LIB_EXT) 46 | case "$(uname -a)" in 47 | Linux*) 48 | LIB_EXT="a" 49 | ;; 50 | Darwin*) 51 | LIB_EXT="a" 52 | ;; 53 | MINGW*) 54 | LIB_EXT="lib" 55 | LIBS="$LIBS -lintl" 56 | ;; 57 | esac 58 | 59 | # VEX stuff 60 | AC_SUBST(VEX_DIR) 61 | VEX_DIR=`pwd`/'VEX' 62 | VEX_VERSION=2201 63 | 64 | AC_SUBST(INCDIRS) 65 | 66 | rm -f libasmir/makefile.inc 67 | echo "VEX_DIR=${VEX_DIR}" >> libasmir/makefile.inc 68 | echo "LIBASMIR_CXXFLAGS=-I${VEX_DIR}/pub -I`pwd`/src/include $CXXFLAGS" >> libasmir/makefile.inc 69 | echo "LIBASMIR_LDFLAGS=-L${VEX_DIR} -L`pwd`/src $LDFLAGS" >> libasmir/makefile.inc 70 | echo "LIBASMIR_LIBS=-lasmir -lvex" >> libasmir/makefile.inc 71 | echo "CLIBS=asmir vex stdc++" >> libasmir/makefile.inc 72 | AC_SUBST(ASMIR_DIR) 73 | ASMIR_DIR="`pwd`/libasmir" 74 | 75 | AC_SUBST(BAP_DIR) 76 | BAP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 77 | 78 | AC_SUBST(OPENREIL_DIR) 79 | OPENREIL_DIR="`pwd`/libopenreil" 80 | 81 | AC_SUBST(PYOPENREIL_DIR) 82 | PYOPENREIL_DIR="`pwd`/pyopenreil" 83 | 84 | echo "prefix=${prefix}" > pyopenreil/src/makefile.inc 85 | 86 | # Checks for header files. 87 | AC_HEADER_STDC 88 | AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h stdio.h string.h unistd.h], , 89 | AC_MSG_ERROR([Standard headers missing])) 90 | 91 | # Checks for typedefs, structures, and compiler characteristics. 92 | AC_HEADER_STDBOOL 93 | AC_C_CONST 94 | AC_TYPE_SIZE_T 95 | AC_DEFINE_UNQUOTED([VEX_VERSION], [${VEX_VERSION}], [The VEX SVN Version]) 96 | 97 | # Checks for library functions. 98 | AC_FUNC_MALLOC 99 | AC_FUNC_MEMCMP 100 | AC_CHECK_FUNCS([bzero memset strstr strtoul]) 101 | 102 | # Check for library function versions 103 | AC_CONFIG_FILES([Makefile 104 | libasmir/Makefile 105 | libasmir/src/Makefile 106 | libopenreil/Makefile 107 | libopenreil/src/Makefile 108 | libopenreil/apps/Makefile 109 | pyopenreil/Makefile]) 110 | AC_OUTPUT 111 | -------------------------------------------------------------------------------- /libasmir/Makefile.am: -------------------------------------------------------------------------------- 1 | # Owned and copyright BitBlaze, 2007. All rights reserved. 2 | # Do not copy, disclose, or distribute without explicit written 3 | # permission. 4 | 5 | SUBDIRS= src 6 | -------------------------------------------------------------------------------- /libasmir/include/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #include 5 | #include "config.h" 6 | 7 | 8 | #define LIBASMIR_VERSION "0.1" 9 | 10 | typedef uint64_t address_t; 11 | 12 | 13 | // 14 | // Logging events 15 | // 16 | #define LOG_INFO 0x00000001 // regular message 17 | #define LOG_WARN 0x00000002 // error 18 | #define LOG_ERR 0x00000004 // warning 19 | #define LOG_BIN 0x00000008 // instruction bytes 20 | #define LOG_ASM 0x00000010 // instruction assembly code 21 | #define LOG_VEX 0x00000020 // instruction VEX code 22 | #define LOG_BIL 0x00000040 // instruction BAP IL code 23 | 24 | // mask for generic purpose log messages 25 | #define LOG_MSG (LOG_INFO | LOG_WARN | LOG_ERR) 26 | 27 | // mask for machine code log messages 28 | #define LOG_INSN (LOG_BIN | LOG_ASM) 29 | 30 | // mask for IR code log messagess 31 | #define LOG_IR (LOG_VEX | LOG_BIL) 32 | 33 | // mask for all log messages 34 | #define LOG_ALL (LOG_MSG | LOG_INSN | LOG_IR) 35 | 36 | // mask to disable all log messages 37 | #define LOG_NONE 0 38 | 39 | 40 | #define LOG_STDERR_DEFAULT LOG_MSG 41 | 42 | #define LOG_TO_STDERR 43 | #define LOG_TO_FILE 44 | 45 | 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | void _panic(const char *msg); 51 | 52 | 53 | #ifdef __cplusplus 54 | 55 | #include 56 | 57 | class BapException 58 | { 59 | public: 60 | 61 | BapException(string s) : reason(s) {}; 62 | string reason; 63 | }; 64 | 65 | void panic(string msg); 66 | 67 | #endif 68 | 69 | 70 | uint32_t log_stderr(uint32_t mask); 71 | 72 | int log_init(uint32_t mask, const char *path); 73 | void log_close(void); 74 | 75 | void log_write(uint32_t level, const char *msg, ...); 76 | size_t log_write_bytes(uint32_t level, const char *msg, size_t len); 77 | 78 | #ifdef __cplusplus 79 | } 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /libasmir/include/disasm.h: -------------------------------------------------------------------------------- 1 | #ifndef DISASM_H 2 | #define DISASM_H 3 | 4 | #define DISASM_MAX_INST_LEN 24 5 | 6 | #define IS_ARM_THUMB(_addr_) ((_addr_) & 1) 7 | 8 | #ifdef __cplusplus 9 | 10 | extern "C" { 11 | 12 | int disasm_insn(VexArch guest, uint8_t *data, address_t addr, string &mnemonic, string &op); 13 | 14 | int disasm_arg_src(VexArch guest, uint8_t *data, address_t addr, vector &args); 15 | int disasm_arg_dst(VexArch guest, uint8_t *data, address_t addr, vector &args); 16 | 17 | } 18 | 19 | #endif 20 | #endif 21 | -------------------------------------------------------------------------------- /libasmir/include/info.h: -------------------------------------------------------------------------------- 1 | #ifndef INFO_H 2 | #define INFO_H 3 | 4 | char *libasmir_version(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /libasmir/include/irtoir-i386.h: -------------------------------------------------------------------------------- 1 | #ifndef IRTOIR_I386_H 2 | #define IRTOIR_I386_H 3 | 4 | void set_eflags_bits(vector *irout, Exp *CF, Exp *PF, Exp *AF, Exp *ZF, Exp *SF, Exp *OF); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /libasmir/include/irtoir-internal.h: -------------------------------------------------------------------------------- 1 | #ifndef IRTOIR_INTERNAL_H 2 | #define IRTOIR_INTERNAL_H 3 | 4 | #include "common.h" 5 | #include "irtoir.h" 6 | 7 | /* We need this for emit_mux/match_mux etc. */ 8 | #ifndef MUX_AS_CJMP 9 | 10 | /* temp + temp + move + move */ 11 | #define MUX_LENGTH 4 12 | 13 | #else 14 | 15 | #error "Please define MUX_LENGTH.. I think it is probably 6." 16 | #define MUX_LENGTH 6 17 | 18 | #endif 19 | 20 | /* Offset from end of mux to setting of CC_OP */ 21 | #define MUX_OFFSET 2 22 | 23 | #define MUX_SUB (MUX_LENGTH + MUX_OFFSET - 1) 24 | 25 | /* Undefined value for CC_OP */ 26 | #define CC_OP_UNDEF -1 27 | 28 | 29 | #define MAX_VEX_FN_ARGS 6 30 | 31 | /* See INTERNAL_VEX_FN_ARG_LIST in stmt.h */ 32 | typedef struct internal_vex_fn_arg_s 33 | { 34 | IRType type; 35 | IRTemp temp; 36 | 37 | } internal_vex_fn_arg; 38 | 39 | typedef struct internal_vex_fn_arg_list_s 40 | { 41 | int count; 42 | internal_vex_fn_arg args[MAX_VEX_FN_ARGS]; 43 | 44 | } internal_vex_fn_arg_list; 45 | 46 | 47 | Temp *mk_reg(string name, reg_t width); 48 | reg_t IRType_to_reg_type(IRType type); 49 | reg_t regt_of_irexpr(IRSB *irbb, IRExpr *e); 50 | 51 | reg_t get_exp_type(Exp *exp); 52 | 53 | inline int get_type_size(reg_t typ) 54 | { 55 | return Exp::reg_to_bits(typ); 56 | } 57 | 58 | string translate_tmp_name(bap_context_t *context, IRType type, IRTemp tmp); 59 | string translate_tmp_name(bap_context_t *context, IRSB *irbb, IRExpr *expr, IRTemp tmp); 60 | IRType translate_tmp_type(bap_context_t *context, IRSB *irbb, IRExpr *expr); 61 | 62 | Temp *mk_temp(string name, IRType ty); 63 | Temp *mk_temp(reg_t type, vector *stmts); 64 | Temp *mk_temp(IRType ty, vector *stmts); 65 | 66 | Label *mk_dest_label(Addr64 dest); 67 | Name *mk_dest_name(Addr64 dest); 68 | 69 | Exp *translate_expr(bap_context_t *context, IRExpr *expr, IRSB *irbb, vector *irout); 70 | 71 | Exp *emit_mux0x(vector *irout, reg_t type, Exp *cond, Exp *exp0, Exp *expX); 72 | int match_mux0x(vector *ir, unsigned int i, Exp **cond, Exp **exp0, Exp **expx, Exp **res); 73 | 74 | extern bool use_eflags_thunks; 75 | extern bool use_simple_segments; 76 | 77 | // 78 | // arch specific functions used in irtoir.cpp 79 | // 80 | 81 | // 82 | // These typedefs are specifically for casting mod_eflags_func to the 83 | // function that accepts the right number of arguments 84 | // 85 | typedef vector Mod_Func_0(bap_context_t *context); 86 | typedef vector Mod_Func_2(bap_context_t *context, reg_t, Exp *, Exp *); 87 | typedef vector Mod_Func_3(bap_context_t *context, reg_t, Exp *, Exp *, Exp *); 88 | 89 | void modify_eflags_helper(bap_context_t *context, bap_block_t *block, string op, reg_t type, int argnum, Mod_Func_0 *mod_eflags_func); 90 | 91 | // defined in irtoir.cpp 92 | void set_flag(vector *irout, reg_t type, Temp *flag, Exp *cond); 93 | 94 | void del_get_thunk(bap_block_t *block); 95 | int del_put_thunk(bap_block_t *block, int op, int dep1, int dep2, int ndep, int mux0x); 96 | void get_put_thunk(bap_block_t *block, int *op, int *dep1, int *dep2, int *ndep, int *mux0x); 97 | 98 | void del_get_itstate(bap_block_t *block); 99 | void del_put_itstate(bap_block_t *block, int itstate); 100 | void get_put_itstate(bap_block_t *block, int *itstate); 101 | 102 | // defined in irtoir-i386.cpp 103 | vector i386_get_reg_decls(); 104 | Exp *i386_translate_get(bap_context_t *context, IRExpr *expr, IRSB *irbb, vector *irout); 105 | Stmt *i386_translate_put(bap_context_t *context, IRStmt *stmt, IRSB *irbb, vector *irout); 106 | Exp *i386_translate_ccall(bap_context_t *context, IRExpr *expr, IRSB *irbb, vector *irout); 107 | void i386_modify_flags(bap_context_t *context, bap_block_t *block); 108 | bool i386_op_is_very_broken(VexArch guest, string op); 109 | 110 | // defined in irtoir-arm.cpp 111 | vector arm_get_reg_decls(); 112 | Exp *arm_translate_get(bap_context_t *context, IRExpr *expr, IRSB *irbb, vector *irout); 113 | Stmt *arm_translate_put(bap_context_t *context, IRStmt *stmt, IRSB *irbb, vector *irout); 114 | Exp *arm_translate_ccall(bap_context_t *context, IRExpr *expr, IRSB *irbb, vector *irout); 115 | void arm_modify_flags(bap_context_t *context, bap_block_t *block); 116 | void arm_modify_itstate(bap_context_t *context, bap_block_t *block); 117 | void arm_modify_itstate_cond(bap_context_t *context, bap_block_t *block); 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /libasmir/include/irtoir.h: -------------------------------------------------------------------------------- 1 | #ifndef IRTOIR_H 2 | #define IRTOIR_H 3 | 4 | typedef struct bap_block_s bap_block_t; 5 | typedef struct bap_context_s bap_context_t; 6 | 7 | // 8 | // VEX headers (inside Valgrind/VEX/pub) 9 | // 10 | #include "vexmem.h" 11 | #include "libvex.h" 12 | 13 | #ifdef __cplusplus 14 | 15 | #include 16 | 17 | #include "stmt.h" 18 | 19 | // 20 | // A struct that encapsulates the stages of translation of 1 asm instruction. 21 | // inst is the original instruction. 22 | // vex_ir is inst translated into a block of VEX IR. 23 | // bap_ir is inst translated into a block of Vine IR from its VEX IR translation. 24 | // 25 | struct bap_block_s 26 | { 27 | address_t inst; 28 | int inst_size; 29 | 30 | string str_mnem; 31 | string str_op; 32 | 33 | IRSB *vex_ir; 34 | vector *bap_ir; 35 | }; 36 | 37 | 38 | typedef struct flag_thunks_s 39 | { 40 | // see CC_OP word description for target architecture in VEX documentation 41 | int op; 42 | 43 | } flag_thunks_t; 44 | 45 | // 46 | // Structure that keeps global state of translation process. 47 | // 48 | struct bap_context_s 49 | { 50 | // current architecture 51 | VexArch guest; 52 | 53 | // address and size of current instruction 54 | address_t inst; 55 | int inst_size; 56 | 57 | // special Exp to record the AST for bit shift instructions 58 | Exp *count_opnd; 59 | 60 | // to keep current values of VEX flag thunk descriptors 61 | flag_thunks_t flag_thunks; 62 | 63 | // to keep current value of ITSTATE register 64 | uint32_t itstate; 65 | }; 66 | 67 | //====================================================================== 68 | // 69 | // Translation functions. These should not be used directly unless you 70 | // understand exactly how they work and have a specific need for them. 71 | // If you just wanna translate a program, see generate_vex_ir and 72 | // generate_bap_ir at the bottom. They wrap these functions and 73 | // provide an easier interface for translation. 74 | // 75 | //====================================================================== 76 | 77 | extern "C" 78 | { 79 | 80 | // 81 | // Initializes VEX. This function must be called before translate_insn 82 | // can be used. 83 | // vexir.c 84 | void translate_init(); 85 | 86 | // 87 | // Translates 1 asm instruction (in byte form) into a block of VEX IR 88 | // 89 | // \param insn_start Pointer to bytes of instruction 90 | // \param insn_addr Address of the instruction in its own address space 91 | // \return An IRSB containing the VEX IR translation of the given instruction 92 | // vexir.c 93 | IRSB *translate_insn(VexArch guest, unsigned char *insn_start, unsigned int insn_addr, int *insn_size); 94 | 95 | // 96 | // Translate an IRSB into a vector of Stmts in our IR 97 | vector *translate_irbb(bap_context_t *context, IRSB *irbb); 98 | 99 | } 100 | 101 | 102 | //====================================================================== 103 | // 104 | // Utility functions that wrap the raw translation functions. 105 | // These are what should be used to do the actual translation. 106 | // See print-ir.cpp in ../../apps for examples of how to use these. 107 | // 108 | //====================================================================== 109 | 110 | // Initialize IR translator context 111 | bap_context_t *init_bap_context(VexArch guest); 112 | 113 | // Take an instrs and translate it into a VEX IR block 114 | // and store it in a bap block 115 | bap_block_t* generate_vex_ir(bap_context_t *context, uint8_t *data, address_t inst); 116 | 117 | // Same as generate_vex_ir, but only for an address range 118 | vector generate_vex_ir(bap_context_t *context, uint8_t *data, address_t start, address_t end); 119 | 120 | // Take a bap block that has gone through VEX translation and translate it 121 | // to Vine IR. 122 | void generate_bap_ir(bap_context_t *context, bap_block_t *block); 123 | 124 | // 125 | // Take a vector of bap blocks that have gone through VEX translation 126 | // and translate them to Vine IR 127 | // 128 | // \param vblocks Vector of bap blocks with valid VEX IR translations 129 | // \return Vector of bap blocks with the bap_ir field filled in 130 | // 131 | vector generate_bap_ir(bap_context_t *context, vector vblocks); 132 | 133 | // Get registers list for guest's architecture 134 | vector get_reg_decls(bap_context_t *context); 135 | 136 | extern "C" 137 | { 138 | typedef struct vector bap_blocks_t; 139 | 140 | #endif // __cplusplus 141 | 142 | #ifdef __cplusplus 143 | } 144 | #endif 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /libasmir/include/irvisitor.h: -------------------------------------------------------------------------------- 1 | #ifndef IRVISITOR_H 2 | #define IRVISITOR_H 3 | 4 | class VarDecl; 5 | class Temp; 6 | class Mem; 7 | class UnOp; 8 | class BinOp; 9 | class Constant; 10 | class Phi; 11 | class Special; 12 | class Jmp; 13 | class CJmp; 14 | class Label; 15 | class Move; 16 | class Comment; 17 | class ExpStmt; 18 | class Unknown; 19 | class Cast; 20 | class Name; 21 | class Exp; 22 | class Let; 23 | class Call; 24 | class Return; 25 | class Func; 26 | class Assert; 27 | class Internal; 28 | 29 | class IRVisitor 30 | { 31 | public: 32 | 33 | IRVisitor() {}; 34 | virtual void visitBinOp(BinOp *) = 0; 35 | virtual void visitUnOp(UnOp *) = 0; 36 | virtual void visitConstant(Constant *) = 0; 37 | virtual void visitTemp(Temp *) = 0; 38 | virtual void visitPhi(Phi *) = 0; 39 | virtual void visitSpecial(Special *) = 0; 40 | virtual void visitMem(Mem *) = 0; 41 | virtual void visitUnknown(Unknown *) = 0; 42 | virtual void visitCast(Cast *) = 0; 43 | virtual void visitName(Name *) = 0; 44 | virtual void visitJmp(Jmp *) = 0; 45 | virtual void visitCJmp(CJmp *) = 0; 46 | virtual void visitLabel(Label *) = 0; 47 | virtual void visitMove(Move *) = 0; 48 | virtual void visitComment(Comment *) = 0; 49 | virtual void visitExpStmt(ExpStmt *) = 0; 50 | virtual void visitVarDecl(VarDecl *) = 0; 51 | virtual void visitLet(Let *) = 0; 52 | virtual void visitCall(Call *) = 0; 53 | virtual void visitReturn(Return *) = 0; 54 | virtual void visitFunc(Func *) = 0; 55 | virtual void visitAssert(Assert *) = 0; 56 | virtual void visitInternal(Internal *) = 0; 57 | virtual ~IRVisitor() {}; 58 | }; 59 | 60 | class DefaultIRVisitor : public virtual IRVisitor 61 | { 62 | public: 63 | 64 | DefaultIRVisitor() {}; 65 | virtual void visitBinOp(BinOp *); 66 | virtual void visitUnOp(UnOp *); 67 | virtual void visitConstant(Constant *); 68 | virtual void visitTemp(Temp *); 69 | virtual void visitPhi(Phi *); 70 | virtual void visitSpecial(Special *); 71 | virtual void visitMem(Mem *); 72 | virtual void visitUnknown(Unknown *); 73 | virtual void visitCast(Cast *); 74 | virtual void visitName(Name *); 75 | virtual void visitJmp(Jmp *); 76 | virtual void visitCJmp(CJmp *); 77 | virtual void visitLabel(Label *); 78 | virtual void visitMove(Move *); 79 | virtual void visitComment(Comment *); 80 | virtual void visitExpStmt(ExpStmt *); 81 | virtual void visitVarDecl(VarDecl *); 82 | virtual void visitLet(Let *); 83 | virtual void visitCall(Call *); 84 | virtual void visitReturn(Return *); 85 | virtual void visitFunc(Func *); 86 | virtual void visitAssert(Assert *); 87 | virtual void visitInternal(Internal *); 88 | virtual ~DefaultIRVisitor() {}; 89 | }; 90 | 91 | class IRChangeVisitor : public IRVisitor 92 | { 93 | public: 94 | 95 | virtual ~IRChangeVisitor() {}; 96 | IRChangeVisitor() {}; 97 | 98 | virtual void visitBinOp(BinOp *); 99 | virtual void visitUnOp(UnOp *); 100 | virtual void visitConstant(Constant *); 101 | virtual void visitTemp(Temp *); 102 | virtual void visitPhi(Phi *); 103 | virtual void visitSpecial(Special *); 104 | virtual void visitMem(Mem *); 105 | virtual void visitUnknown(Unknown *); 106 | virtual void visitCast(Cast *); 107 | virtual void visitName(Name *); 108 | virtual void visitJmp(Jmp *); 109 | virtual void visitCJmp(CJmp *); 110 | virtual void visitLabel(Label *); 111 | virtual void visitMove(Move *); 112 | virtual void visitComment(Comment *); 113 | virtual void visitExpStmt(ExpStmt *); 114 | virtual void visitVarDecl(VarDecl *); 115 | virtual void visitLet(Let *); 116 | virtual void visitCall(Call *); 117 | virtual void visitReturn(Return *); 118 | virtual void visitFunc(Func *); 119 | virtual void visitAssert(Assert *); 120 | virtual void visitInternal(Internal *); 121 | 122 | protected: 123 | 124 | Exp *ret; 125 | }; 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /libasmir/include/jumpbuf.h: -------------------------------------------------------------------------------- 1 | #ifndef JUMPBUF_H 2 | #define JUMPBUF_H 3 | 4 | #include 5 | 6 | /* Jump buffer used to return from VEX errors */ 7 | extern jmp_buf vex_error; 8 | extern char jmp_buf_set; 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /libasmir/include/vexmem.h: -------------------------------------------------------------------------------- 1 | #ifndef VEXMEM_H 2 | #define VEXMEM_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | #include "libvex.h" 10 | 11 | void *vx_Alloc(Int nbytes); 12 | void vx_FreeAll(); 13 | 14 | IRSB* vx_dopyIRSB(IRSB* bb); 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /libasmir/src/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | RANLIB = @RANLIB@ 3 | 4 | noinst_LIBRARIES = libasmir.a 5 | 6 | AM_CFLAGS = -I@VEX_DIR@/pub -I@DISASM_INC@ -I../include -fPIC -DGET_OPERANDS 7 | 8 | AM_CXXFLAGS = $(AM_CFLAGS) 9 | 10 | libasmir_a_SOURCES = \ 11 | stmt.cpp \ 12 | exp.cpp \ 13 | common.cpp \ 14 | disasm-@DISASM_NAME@.cpp \ 15 | irtoir.cpp \ 16 | irtoir-i386.cpp \ 17 | irtoir-arm.cpp \ 18 | vexir.c \ 19 | vexmem.c 20 | -------------------------------------------------------------------------------- /libasmir/src/common.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | 14 | #include "common.h" 15 | 16 | #ifdef LOG_TO_STDERR 17 | 18 | uint32_t log_stderr_mask = LOG_STDERR_DEFAULT; 19 | 20 | #endif 21 | 22 | #ifdef LOG_TO_FILE 23 | 24 | FILE *log_file_fd = NULL; 25 | uint32_t log_file_mask = 0; 26 | 27 | #endif 28 | 29 | //---------------------------------------------------------------------- 30 | // Logging functions 31 | //---------------------------------------------------------------------- 32 | uint32_t log_stderr(uint32_t mask) 33 | { 34 | 35 | #ifdef LOG_TO_STDERR 36 | 37 | int ret = log_stderr_mask; 38 | 39 | log_stderr_mask = mask; 40 | 41 | return ret; 42 | 43 | #else 44 | 45 | return 0; 46 | 47 | #endif 48 | 49 | } 50 | 51 | int log_init(uint32_t mask, const char *path) 52 | { 53 | 54 | #ifdef LOG_TO_FILE 55 | 56 | log_close(); 57 | 58 | // start new log file 59 | if ((log_file_fd = fopen(path, "w")) != NULL) 60 | { 61 | log_file_mask = mask; 62 | return 0; 63 | } 64 | else 65 | { 66 | return errno; 67 | } 68 | 69 | #endif 70 | 71 | return EINVAL; 72 | } 73 | 74 | void log_close(void) 75 | { 76 | 77 | #ifdef LOG_TO_FILE 78 | 79 | if (log_file_fd) 80 | { 81 | fclose(log_file_fd); 82 | log_file_fd = NULL; 83 | } 84 | 85 | #endif 86 | 87 | } 88 | 89 | void log_write(uint32_t level, const char *msg, ...) 90 | { 91 | va_list mylist; 92 | va_start(mylist, msg); 93 | 94 | char *buff = NULL; 95 | int len = vsnprintf(NULL, 0, msg, mylist) + 1; 96 | 97 | va_end(mylist); 98 | va_start(mylist, msg); 99 | 100 | // allocate buffer for message string 101 | if (len > 0 && (buff = (char *)malloc(len + 1))) 102 | { 103 | memset(buff, 0, len + 1); 104 | 105 | if (vsnprintf(buff, len, msg, mylist) < 0) 106 | { 107 | free(buff); 108 | buff = NULL; 109 | } 110 | else 111 | { 112 | strcat(buff, "\n"); 113 | } 114 | } 115 | 116 | va_end(mylist); 117 | 118 | if (buff) 119 | { 120 | log_write_bytes(level, buff, strlen(buff)); 121 | free(buff); 122 | } 123 | } 124 | 125 | size_t log_write_bytes(uint32_t level, const char *msg, size_t len) 126 | { 127 | size_t ret = 0; 128 | 129 | #ifdef LOG_TO_STDERR 130 | 131 | if (level & log_stderr_mask) 132 | { 133 | // write message to stderr 134 | ret = fwrite(msg, len, 1, stderr); 135 | } 136 | 137 | #endif 138 | 139 | #ifdef LOG_TO_FILE 140 | 141 | if (level & log_file_mask) 142 | { 143 | if (log_file_fd) 144 | { 145 | // write message to file 146 | ret = fwrite(msg, len, 1, log_file_fd); 147 | } 148 | } 149 | 150 | #endif 151 | 152 | return ret; 153 | } 154 | 155 | //---------------------------------------------------------------------- 156 | // A panic function that prints a msg and terminates the program 157 | //---------------------------------------------------------------------- 158 | void panic(string msg) 159 | { 160 | string str = "panic(): " + msg; 161 | 162 | throw BapException(str); 163 | } 164 | 165 | void _panic(const char *msg) 166 | { 167 | panic(string(msg)); 168 | } 169 | -------------------------------------------------------------------------------- /libopenreil/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS= src apps 3 | -------------------------------------------------------------------------------- /libopenreil/apps/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_PROGRAMS = translate-inst 3 | 4 | include_HEADERS = ../include/reil_ir.h ../include/libopenreil.h 5 | 6 | LDADD = @OPENREIL_DIR@/src/libopenreil.a 7 | 8 | AM_CXXFLAGS = -I../include 9 | 10 | translate_inst_SOURCES = translate-inst.cpp 11 | -------------------------------------------------------------------------------- /libopenreil/apps/translate-inst.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "libopenreil.h" 9 | 10 | #define LOG_NAME "translate-inst.log" 11 | 12 | int reil_inst_handler(reil_inst_t *inst, void *context) 13 | { 14 | // print instruction representation to the stdout 15 | reil_inst_print(inst); 16 | 17 | return 0; 18 | } 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | if (argc < 3) 23 | { 24 | printf("USAGE: tarnslate-inst arch hex_bytes\n"); 25 | return 0; 26 | } 27 | 28 | reil_arch_t arch; 29 | char *arch_name = argv[1]; 30 | 31 | int inst_len = 0; 32 | uint8_t inst[MAX_INST_LEN]; 33 | reil_addr_t addr = 0; 34 | 35 | memset(inst, 0, sizeof(inst)); 36 | 37 | if (!strcmp(arch_name, "i386") || !strcmp(arch_name, "x86")) 38 | { 39 | printf("[+] Using i386 architecture\n"); 40 | 41 | // set target architecture 42 | arch = ARCH_X86; 43 | } 44 | else if (!strcmp(arch_name, "arm")) 45 | { 46 | printf("[+] Using ARM architecture\n"); 47 | 48 | // set target architecture 49 | arch = ARCH_ARM; 50 | } 51 | else 52 | { 53 | printf("ERROR: Bad architecture\n"); 54 | return -1; 55 | } 56 | 57 | for (int i = 2; i < argc; i++) 58 | { 59 | char *arg = argv[i]; 60 | 61 | // get additional command line options 62 | if (inst_len == 0) 63 | { 64 | if (!strcmp(arg, "--debug") || !strcmp(arg, "-d")) 65 | { 66 | printf("[+] Log name is %s\n", LOG_NAME); 67 | 68 | // enable extra debug output 69 | reil_log_init(REIL_LOG_ALL, LOG_NAME); 70 | continue; 71 | } 72 | else if (!strcmp(arg, "--thumb") || !strcmp(arg, "-t")) 73 | { 74 | printf("[+] Disassembling in Thumb mode\n"); 75 | 76 | // enable thumb mode 77 | addr = REIL_ARM_THUMB(addr); 78 | continue; 79 | } 80 | } 81 | 82 | errno = 0; 83 | 84 | // get user specified bytes to dissassembly 85 | inst[inst_len] = strtol(argv[i], NULL, 16); 86 | inst_len += 1; 87 | 88 | if (errno == EINVAL) 89 | { 90 | printf("ERROR: Invalid hex value\n"); 91 | return -1; 92 | } 93 | } 94 | 95 | // translate single instruction 96 | void *reil = reil_init(arch, reil_inst_handler, NULL); 97 | if (reil) 98 | { 99 | reil_translate(reil, addr, inst, inst_len); 100 | reil_close(reil); 101 | } 102 | 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /libopenreil/include/libopenreil.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LIBOPENREIL_H 3 | #define LIBOPENREIL_H 4 | 5 | // IR format definitions 6 | #include "reil_ir.h" 7 | 8 | 9 | // max. size of one machine instruction (all arhitectures) 10 | #define MAX_INST_LEN 24 11 | 12 | // return value that indicates initialization/translation error 13 | #define REIL_ERROR -1 14 | 15 | // enable under construction features 16 | #define TESTING 17 | 18 | 19 | /* 20 | In ARCH_ARM mode least significant bit of instruction address 21 | indicates Thumb mode enabled. 22 | */ 23 | #define REIL_ARM_THUMB(_addr_) ((_addr_) | 1) 24 | 25 | /* 26 | Debug information type constants for mask argument of reil_log_init() 27 | */ 28 | #define REIL_LOG_INFO 0x00000001 // regular message 29 | #define REIL_LOG_WARN 0x00000002 // error 30 | #define REIL_LOG_ERR 0x00000004 // warning 31 | #define REIL_LOG_BIN 0x00000008 // instruction bytes 32 | #define REIL_LOG_ASM 0x00000010 // instruction assembly code 33 | #define REIL_LOG_VEX 0x00000020 // instruction VEX code 34 | #define REIL_LOG_BIL 0x00000040 // instruction BAP IL code 35 | 36 | // all log messages 37 | #define REIL_LOG_ALL 0x7FFFFFFF 38 | 39 | // disable log messages 40 | #define REIL_LOG_NONE 0 41 | 42 | // by default we prints warnings, errors and info to stderr 43 | #define REIL_LOG_DEFAULT (LOG_INFO | LOG_WARN | LOG_ERR) 44 | 45 | 46 | typedef void * reil_t; 47 | 48 | typedef enum _reil_arch_t 49 | { 50 | ARCH_X86, 51 | ARCH_ARM 52 | 53 | } reil_arch_t; 54 | 55 | 56 | #ifdef __cplusplus 57 | extern "C" { 58 | #endif 59 | 60 | /* 61 | Prints REIL instruction to console. 62 | */ 63 | void reil_inst_print(reil_inst_t *inst); 64 | 65 | 66 | typedef int (* reil_inst_handler_t)(reil_inst_t *inst, void *context); 67 | 68 | /* 69 | Initialize REIL translator. 70 | */ 71 | reil_t reil_init(reil_arch_t arch, reil_inst_handler_t handler, void *context); 72 | 73 | /* 74 | Close translator. 75 | */ 76 | void reil_close(reil_t reil); 77 | 78 | /* 79 | Initialize debug log. 80 | * Individual bits of mask argument tells what kind of information 81 | we need to include into the log (see REIL_LOG_* constants). 82 | * Log file path can be specified in path argument, NULL value 83 | indicates that we need to print debug information only to stderr. 84 | */ 85 | int reil_log_init(uint32_t mask, const char *path); 86 | 87 | /* 88 | Closes currently opened log file. 89 | */ 90 | void reil_log_close(void); 91 | 92 | int reil_translate(reil_t reil, reil_addr_t addr, unsigned char *buff, int len); 93 | int reil_translate_insn(reil_t reil, reil_addr_t addr, unsigned char *buff, int len); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif // LIBOPENREIL_H 100 | -------------------------------------------------------------------------------- /libopenreil/include/reil_ir.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef REIL_IR_H 3 | #define REIL_IR_H 4 | 5 | #define REIL_MAX_NAME_LEN 15 6 | 7 | #define IOPT_CALL 0x00000001 8 | #define IOPT_RET 0x00000002 9 | #define IOPT_BB_END 0x00000004 10 | #define IOPT_ASM_END 0x00000008 11 | 12 | typedef enum _reil_op_t 13 | { 14 | I_NONE, // no operation 15 | I_UNK, // unknown instruction 16 | I_JCC, // conditional jump 17 | I_STR, // store value to register 18 | I_STM, // store value to memory 19 | I_LDM, // load value from memory 20 | I_ADD, // addition 21 | I_SUB, // substraction 22 | I_NEG, // negation 23 | I_MUL, // multiplication 24 | I_DIV, // division 25 | I_MOD, // modulus 26 | I_SMUL, // signed multiplication 27 | I_SDIV, // signed division 28 | I_SMOD, // signed modulus 29 | I_SHL, // shift left 30 | I_SHR, // shift right 31 | I_AND, // binary and 32 | I_OR, // binary or 33 | I_XOR, // binary xor 34 | I_NOT, // binary not 35 | I_EQ, // equation 36 | I_LT // less than 37 | 38 | } reil_op_t; 39 | 40 | typedef enum _reil_type_t 41 | { 42 | A_NONE, 43 | A_REG, // target architecture registry operand 44 | A_TEMP, // temporary registry operand 45 | A_CONST, // immediate value 46 | A_LOC // jump location 47 | 48 | } reil_type_t; 49 | 50 | typedef unsigned long long reil_const_t; 51 | typedef unsigned long long reil_addr_t; 52 | typedef unsigned short reil_inum_t; 53 | 54 | typedef enum _reil_size_t { U1, U8, U16, U32, U64 } reil_size_t; 55 | 56 | typedef struct _reil_arg_t 57 | { 58 | reil_type_t type; 59 | reil_size_t size; 60 | reil_const_t val; 61 | reil_inum_t inum; 62 | char name[REIL_MAX_NAME_LEN]; 63 | 64 | } reil_arg_t; 65 | 66 | typedef struct _reil_raw_t 67 | { 68 | reil_addr_t addr; // address of the original assembly instruction 69 | int size; // .. and it's size 70 | 71 | // pointer to the instruction bytes 72 | unsigned char *data; 73 | 74 | // instruction mnemonic and operands 75 | char *str_mnem; 76 | char *str_op; 77 | 78 | } reil_raw_t; 79 | 80 | typedef struct _reil_inst_t 81 | { 82 | reil_raw_t raw_info; 83 | 84 | reil_inum_t inum; // IR instruction number 85 | reil_op_t op; // opcode 86 | reil_arg_t a, b, c; // arguments 87 | unsigned long long flags; // optional instruction information flags 88 | 89 | } reil_inst_t; 90 | 91 | #endif // REIL_IR_H 92 | -------------------------------------------------------------------------------- /libopenreil/include/reil_translator.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef REIL_TRANSLATOR_H 3 | #define REIL_TRANSLATOR_H 4 | 5 | #define EXPAND_EFLAGS 6 | 7 | #define MAX_REG_NAME_LEN 20 8 | 9 | string to_string_constant(reil_const_t val, reil_size_t size); 10 | string to_string_size(reil_size_t size); 11 | string to_string_operand(reil_arg_t *a); 12 | string to_string_inst_code(reil_op_t inst_code); 13 | 14 | typedef pair TEMPREG_BAP; 15 | 16 | typedef pair BAP_LOC; 17 | typedef pair BAP_LABEL; 18 | 19 | class CReilTranslatorException 20 | { 21 | public: 22 | 23 | CReilTranslatorException(string s) : reason(s) {}; 24 | string reason; 25 | }; 26 | 27 | class CReilFromBilTranslator 28 | { 29 | public: 30 | 31 | CReilFromBilTranslator(VexArch arch, reil_inst_handler_t handler, void *context); 32 | ~CReilFromBilTranslator(); 33 | 34 | void reset_state(bap_block_t *block); 35 | 36 | void process_bil(reil_raw_t *raw_info, bap_block_t *block); 37 | 38 | private: 39 | 40 | int32_t tempreg_find(string name); 41 | int32_t tempreg_alloc(void); 42 | string tempreg_get_name(int32_t tempreg_num); 43 | string tempreg_get(string name); 44 | 45 | uint64_t convert_special(Special *special); 46 | 47 | void convert_operand(Exp *exp, reil_arg_t *reil_arg); 48 | reg_t convert_operand_size(reil_size_t size); 49 | reil_size_t convert_operand_size(reg_t typ); 50 | 51 | Exp *temp_operand(reg_t typ, reil_inum_t inum); 52 | 53 | bool is_unknown_insn(bap_block_t *block); 54 | void process_unknown_insn(void); 55 | void process_empty_insn(void); 56 | 57 | void process_reil_inst(reil_inst_t *reil_inst); 58 | 59 | bool get_bil_label(string name, reil_addr_t *addr); 60 | Stmt *get_bil_stmt(int pos); 61 | 62 | bool is_next_insn_label(Exp *target); 63 | 64 | void process_binop_arshift(reil_inst_t *reil_inst); 65 | void process_binop_neq(reil_inst_t *reil_inst); 66 | void process_binop_le(reil_inst_t *reil_inst); 67 | void process_binop_gt(reil_inst_t *reil_inst); 68 | void process_binop_ge(reil_inst_t *reil_inst); 69 | 70 | bool process_bil_cast(Exp *exp, reil_inst_t *reil_inst); 71 | Exp *process_bil_exp(Exp *exp); 72 | void free_bil_exp(Exp *exp); 73 | 74 | Exp *process_bil_inst(reil_op_t inst, uint64_t inst_flags, Exp *c, Exp *exp); 75 | void process_bil_stmt(Stmt *s, uint64_t inst_flags); 76 | 77 | VexArch guest; 78 | 79 | bap_block_t *current_block; 80 | int current_stmt; 81 | 82 | vector tempreg_bap; 83 | int32_t tempreg_count; 84 | reil_inum_t inst_count; 85 | reil_raw_t *current_raw_info; 86 | bool skip_eflags; 87 | 88 | reil_inst_handler_t inst_handler; 89 | void *inst_handler_context; 90 | 91 | vector translated_insts; 92 | vector translated_labels; 93 | }; 94 | 95 | class CReilTranslator 96 | { 97 | public: 98 | 99 | CReilTranslator(VexArch arch, reil_inst_handler_t handler, void *handler_context); 100 | ~CReilTranslator(); 101 | 102 | int process_inst(address_t addr, uint8_t *data, int size); 103 | 104 | private: 105 | 106 | bap_context_t *context; 107 | CReilFromBilTranslator *translator; 108 | }; 109 | 110 | #endif // REIL_TRANSLATOR_H 111 | -------------------------------------------------------------------------------- /libopenreil/src/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | RANLIB = @RANLIB@ 3 | 4 | lib_LIBRARIES = libopenreil.a 5 | 6 | AM_CFLAGS = -I@VEX_DIR@/pub -I@DISASM_INC@ -I@ASMIR_DIR@/include -I../include -fPIC 7 | 8 | AM_CXXFLAGS = $(AM_CFLAGS) 9 | 10 | libopenreil_a_SOURCES = \ 11 | libopenreil.cpp \ 12 | reil_translator.cpp 13 | 14 | libopenreil.a: $(libopenreil_a_OBJECTS) @VEX_DIR@/libvex.a @ASMIR_DIR@/src/libasmir.a 15 | ./makelib.sh 16 | 17 | -------------------------------------------------------------------------------- /libopenreil/src/makelib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # This shell program joins all static libraries of OpenREIL 5 | # into the single file using ar. 6 | # 7 | # (Yes, I know about MRI scripts, but this way is more reliable) 8 | # 9 | 10 | # delete old library file 11 | [ -f libopenreil.a ] && rm libopenreil.a 12 | 13 | # create temp dir 14 | [ -d .ar_temp ] ; mkdir .ar_temp 15 | cd .ar_temp 16 | 17 | # remove old object files 18 | rm *.o 19 | 20 | # unpack required libs 21 | ar -x ../../../VEX/libvex.a 22 | ar -x ../../../capstone/capstone/libcapstone.a 23 | ar -x ../../../libasmir/src/libasmir.a 24 | 25 | # create final library file 26 | ar -q ../libopenreil.a *.o ../*.o 27 | 28 | # remove temp dir 29 | cd .. && rm -rf .ar_temp 30 | 31 | -------------------------------------------------------------------------------- /pyopenreil/IR.py: -------------------------------------------------------------------------------- 1 | 2 | # IR instruction attributes 3 | IATTR_ASM = 0 4 | IATTR_BIN = 1 5 | IATTR_FLAGS = 2 6 | IATTR_NEXT = 3 7 | IATTR_SRC = 4 8 | IATTR_DST = 5 9 | 10 | # IR instruction flags 11 | IOPT_CALL = 0x00000001 12 | IOPT_RET = 0x00000002 13 | IOPT_BB_END = 0x00000004 14 | IOPT_ASM_END = 0x00000008 15 | IOPT_ELIMINATED = 0x00000010 16 | 17 | MAX_INST_LEN = 24 18 | 19 | REIL_NAMES_INSN = [ 'NONE', 'UNK', 'JCC', 20 | 'STR', 'STM', 'LDM', 21 | 'ADD', 'SUB', 'NEG', 'MUL', 'DIV', 'MOD', 'SMUL', 'SDIV', 'SMOD', 22 | 'SHL', 'SHR', 'AND', 'OR', 'XOR', 'NOT', 23 | 'EQ', 'LT' ] 24 | 25 | REIL_NAMES_SIZE = [ '1', '8', '16', '32', '64' ] 26 | 27 | REIL_NAMES_ARG = [ 'NONE', 'REG', 'TEMP', 'CONST', 'LOC' ] 28 | 29 | 30 | def create_globals(items, list_name, prefix): 31 | 32 | items_list = globals()[list_name] = [] 33 | num = 0 34 | 35 | for it in items: 36 | 37 | globals()[prefix + str(it)] = num 38 | items_list.append(num) 39 | num += 1 40 | 41 | # create global constants for REIL opcodes, sizes and argument types 42 | create_globals(REIL_NAMES_INSN, 'REIL_INSN', 'I_') 43 | create_globals(REIL_NAMES_SIZE, 'REIL_SIZE', 'U') 44 | create_globals(REIL_NAMES_ARG, 'REIL_ARG', 'A_') 45 | 46 | 47 | ARG_TYPE = 0 48 | ARG_SIZE = 1 49 | ARG_LOC = 1 50 | ARG_NAME = 2 51 | ARG_VAL = 2 52 | 53 | # raw IR arguments helpers 54 | Arg_type = lambda arg: arg[ARG_TYPE] # argument type (see REIL_ARG) 55 | Arg_size = lambda arg: arg[ARG_SIZE] # argument size (see REIL_SIZE) 56 | Arg_name = lambda arg: arg[ARG_NAME] # argument name (for A_REG and A_TEMP) 57 | Arg_val = lambda arg: arg[ARG_VAL] # argument value for A_CONST 58 | Arg_loc = lambda arg: arg[ARG_LOC] # argument value for A_LOC 59 | 60 | 61 | INSN_ADDR = 0 62 | INSN_INUM = 1 63 | INSN_OP = 2 64 | INSN_ARGS = 3 65 | INSN_ATTR = 4 66 | 67 | INSN_ADDR_ADDR = 0 68 | INSN_ADDR_SIZE = 1 69 | 70 | # raw IR instruction helpers 71 | Insn_addr = lambda insn: insn[INSN_ADDR][INSN_ADDR_ADDR] # instruction virtual address 72 | Insn_size = lambda insn: insn[INSN_ADDR][INSN_ADDR_SIZE] # assembly code size 73 | Insn_inum = lambda insn: insn[INSN_INUM] # IR subinstruction number 74 | Insn_op = lambda insn: insn[INSN_OP] # operation code 75 | Insn_args = lambda insn: insn[INSN_ARGS] # tuple with 3 arguments 76 | Insn_attr = lambda insn: insn[INSN_ATTR] # instruction attributes 77 | 78 | # get IR instruction address 79 | Insn_ir_addr = lambda insn: ( Insn_addr(insn), Insn_inum(insn) ) 80 | 81 | # 82 | # EoF 83 | # 84 | 85 | -------------------------------------------------------------------------------- /pyopenreil/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | SUBDIRS= src 3 | -------------------------------------------------------------------------------- /pyopenreil/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/pyopenreil/__init__.py -------------------------------------------------------------------------------- /pyopenreil/arch/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/pyopenreil/arch/__init__.py -------------------------------------------------------------------------------- /pyopenreil/arch/arm.py: -------------------------------------------------------------------------------- 1 | from pyopenreil.IR import * 2 | 3 | # architecture name 4 | name = 'arm' 5 | 6 | # size of register 7 | size = U32 8 | 9 | # pointer length 10 | ptr_len = 4 11 | 12 | class Registers: 13 | 14 | # flag registers 15 | flags = ( 'R_NF', 'R_ZF', 'R_CF', 'R_VF' ) 16 | 17 | # general purpose registers 18 | general = ( 'R_R0', 'R_R1', 'R_R2', 'R_R3', 'R_R4', 'R_R5', 'R_R6', 'R_R7', 19 | 'R_R8', 'R_R9', 'R_R10', 'R_R11', 'R_R12', 'R_R13', 'R_R14', 'R_R15T' ) 20 | 21 | # instruction pointer 22 | ip = 'R_R15T' 23 | 24 | # stack pointer 25 | sp = 'R_R13' 26 | 27 | # link register 28 | lr = 'R_R14' 29 | 30 | # accumulator 31 | accum = 'R_R0' 32 | 33 | # all of the registers 34 | all = (( 'R_R0', U32 ), 35 | ( 'R_R1', U32 ), 36 | ( 'R_R2', U32 ), 37 | ( 'R_R3', U32 ), 38 | ( 'R_R4', U32 ), 39 | ( 'R_R5', U32 ), 40 | ( 'R_R6', U32 ), 41 | ( 'R_R7', U32 ), 42 | ( 'R_R8', U32 ), 43 | ( 'R_R9', U32 ), 44 | ( 'R_R10', U32 ), 45 | ( 'R_R11', U32 ), 46 | ( 'R_R12', U32 ), 47 | ( 'R_R13', U32 ), 48 | ( 'R_R14', U32 ), 49 | ( 'R_R15T', U32 ), 50 | 51 | ( 'R_CC_OP', U32 ), 52 | ( 'R_CC_DEP1', U32 ), 53 | ( 'R_CC_DEP2', U32 ), 54 | ( 'R_CC_NDEP', U32 ), 55 | 56 | ( 'R_ITCOND', U1 ) 57 | ) 58 | 59 | # 60 | # EoF 61 | # 62 | -------------------------------------------------------------------------------- /pyopenreil/arch/x86.py: -------------------------------------------------------------------------------- 1 | from pyopenreil.IR import * 2 | 3 | # architecture name 4 | name = 'x86' 5 | 6 | # size of register 7 | size = U32 8 | 9 | # pointer length 10 | ptr_len = 4 11 | 12 | class Registers: 13 | 14 | # flag registers 15 | flags = ( 'R_ZF', 'R_PF', 'R_CF', 'R_AF', 'R_SF', 'R_OF', 'R_DFLAG' ) 16 | 17 | # general purpose registers 18 | general = ( 'R_EAX', 'R_EBX', 'R_ECX', 'R_EDX', 'R_ESI', 'R_EDI', 'R_EBP', 'R_ESP' ) 19 | 20 | # instruction pointer 21 | ip = 'R_EIP' 22 | 23 | # stack pointer 24 | sp = 'R_ESP' 25 | 26 | # accumulator 27 | accum = 'R_EAX' 28 | 29 | # all of the registers 30 | all = (( 'EFLAGS', U32 ), 31 | ( 'R_LDT', U32 ), 32 | ( 'R_GDT', U32 ), 33 | ( 'R_DFLAG', U32 ), 34 | 35 | ( 'R_CS', U16 ), 36 | ( 'R_DS', U16 ), 37 | ( 'R_ES', U16 ), 38 | ( 'R_FS', U16 ), 39 | ( 'R_GS', U16 ), 40 | ( 'R_SS', U16 ), 41 | 42 | # Status bit flags 43 | ( 'R_CF', U1 ), 44 | ( 'R_CF', U1 ), 45 | ( 'R_PF', U1 ), 46 | ( 'R_AF', U1 ), 47 | ( 'R_ZF', U1 ), 48 | ( 'R_SF', U1 ), 49 | ( 'R_OF', U1 ), 50 | ( 'R_CC_OP', U32 ), 51 | ( 'R_CC_DEP1', U32 ), 52 | ( 'R_CC_DEP2', U32 ), 53 | ( 'R_CC_NDEP', U32 ), 54 | 55 | # other flags 56 | ( 'R_DFLAG', U32 ), # Direction Flag 57 | ( 'R_IDFLAG', U1 ), # Id flag (support for cpu id instruction) 58 | ( 'R_ACFLAG', U1 ), # Alignment check 59 | ( 'R_EMWARN', U32 ), 60 | 61 | # General purpose 32-bit registers 62 | ( 'R_EAX', U32 ), 63 | ( 'R_EBX', U32 ), 64 | ( 'R_ECX', U32 ), 65 | ( 'R_EDX', U32 ), 66 | ( 'R_ESI', U32 ), 67 | ( 'R_EDI', U32 ), 68 | ( 'R_EBP', U32 ), 69 | ( 'R_ESP', U32 ), 70 | 71 | # 16-bit registers (bits 0-15) 72 | ( 'R_AX', U16 ), 73 | ( 'R_BX', U16 ), 74 | ( 'R_CX', U16 ), 75 | ( 'R_DX', U16 ), 76 | ( 'R_BP', U16 ), 77 | ( 'R_SI', U16 ), 78 | ( 'R_DI', U16 ), 79 | ( 'R_SP', U16 ), 80 | 81 | # 8-bit registers (bits 0-7) 82 | ( 'R_AL', U8 ), 83 | ( 'R_BL', U8 ), 84 | ( 'R_CL', U8 ), 85 | ( 'R_DL', U8 ), 86 | 87 | # 8-bit registers (bits 8-15) 88 | ( 'R_AH', U8 ), 89 | ( 'R_BH', U8 ), 90 | ( 'R_CH', U8 ), 91 | ( 'R_DH', U8 ), 92 | 93 | # 32-bit segment base registers 94 | ( 'R_CS_BASE', U32 ), 95 | ( 'R_DS_BASE', U32 ), 96 | ( 'R_ES_BASE', U32 ), 97 | ( 'R_FS_BASE', U32 ), 98 | ( 'R_GS_BASE', U32 ), 99 | ( 'R_SS_BASE', U32 ) 100 | ) 101 | 102 | # 103 | # EoF 104 | # 105 | -------------------------------------------------------------------------------- /pyopenreil/scripts/gdb_reiltrans.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import gdb 3 | from pyopenreil.REIL import * 4 | from pyopenreil.utils import GDB 5 | 6 | class CommandREILTranslate(gdb.Command): 7 | 8 | DEF_ARCH = ARCH_X86 9 | 10 | translate = { 'insn': lambda tr, addr: tr.get_insn(addr), \ 11 | 'block': lambda tr, addr: tr.get_bb(addr), \ 12 | 'func': lambda tr, addr: tr.get_func(addr) } 13 | 14 | def __init__(self): 15 | 16 | self.arch = self.DEF_ARCH 17 | 18 | super(CommandREILTranslate, self).__init__('reiltrans', gdb.COMMAND_OBSCURE) 19 | 20 | def usage(self): 21 | 22 | print 'USAGE: reiltrans insn|block|func
[options]' 23 | 24 | def invoke(self, arg, from_tty): 25 | 26 | args = arg.split(' ') 27 | 28 | if len(arg.strip()) == 0 or len(args) < 2: 29 | 30 | return self.usage() 31 | 32 | mode, addr = args[0], int(args[1], 16) 33 | arch = self.DEF_ARCH 34 | path = None 35 | 36 | if not mode in self.translate.keys(): 37 | 38 | return self.usage() 39 | 40 | for i in range(2, len(args)): 41 | 42 | val = args[i] 43 | 44 | if (val == '-a' or val == '--arch') and len(args) >= i + 1: 45 | 46 | arch = args[i + 1] 47 | 48 | elif (val == '-f' or val == '--to-file') and len(args) >= i + 1: 49 | 50 | path = args[i + 1] 51 | 52 | # initialize OpenREIL stuff 53 | reader = GDB.Reader(arch, gdb.selected_inferior()) 54 | tr = CodeStorageTranslator(reader) 55 | 56 | # translate function and enumerate it's basic blocks 57 | insn_list = self.translate[mode](tr, addr) 58 | 59 | if path is not None: 60 | 61 | # save serialized function IR 62 | tr.storage.to_file(path) 63 | 64 | print '%d instructions saved to %s' % (len(insn_list), path) 65 | 66 | else: 67 | 68 | # print translated instructions 69 | print insn_list 70 | 71 | 72 | CommandREILTranslate() 73 | 74 | # 75 | # EoF 76 | # 77 | -------------------------------------------------------------------------------- /pyopenreil/scripts/ida_translate_func.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import idc 3 | from pyopenreil.REIL import * 4 | from pyopenreil.utils import IDA 5 | 6 | DEF_ARCH = ARCH_X86 7 | 8 | # get address of the current function 9 | addr = idc.ScreenEA() 10 | 11 | arch = DEF_ARCH 12 | path = os.path.join(os.getcwd(), 'sub_%.8X.ir' % addr) 13 | 14 | # initialize OpenREIL stuff 15 | reader = IDA.Reader(arch) 16 | storage = CodeStorageMem(arch) 17 | tr = CodeStorageTranslator(reader, storage) 18 | 19 | # translate function and enumerate it's basic blocks 20 | func = tr.get_func(addr) 21 | 22 | for bb in func.bb_list: print bb 23 | 24 | print '[*] Saving instructions into the %s' % path 25 | print '[*] %d IR instructions in %d basic blocks translated' % (len(func), len(func.bb_list)) 26 | 27 | # save function IR into the JSON file 28 | storage.to_file(path) 29 | -------------------------------------------------------------------------------- /pyopenreil/scripts/kd_reiltrans.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | import pykd 3 | from pyopenreil.REIL import * 4 | from pyopenreil.utils import kd 5 | 6 | DEF_ARCH = ARCH_X86 7 | 8 | translate = { 'insn': lambda tr, addr: tr.get_insn(addr), \ 9 | 'block': lambda tr, addr: tr.get_bb(addr), \ 10 | 'func': lambda tr, addr: tr.get_func(addr) } 11 | 12 | def usage(argv): 13 | 14 | print 'USAGE: %s insn|block|func
[options]' % os.path.basename(argv[0]) 15 | 16 | def main(argv): 17 | 18 | if len(argv) < 3: 19 | 20 | return usage(argv) 21 | 22 | mode, addr = argv[1], pykd.expr(argv[2]) 23 | arch = DEF_ARCH 24 | path = None 25 | 26 | if not mode in translate.keys(): 27 | 28 | return usage(argv) 29 | 30 | for i in range(3, len(argv)): 31 | 32 | val = argv[i] 33 | 34 | if (val == '-a' or val == '--arch') and len(argv) >= i + 1: 35 | 36 | arch = argv[i + 1] 37 | 38 | elif (val == '-f' or val == '--to-file') and len(argv) >= i + 1: 39 | 40 | path = argv[i + 1] 41 | 42 | # initialize OpenREIL stuff 43 | reader = kd.Reader(arch) 44 | tr = CodeStorageTranslator(reader) 45 | 46 | # translate function and enumerate it's basic blocks 47 | insn_list = translate[mode](tr, addr) 48 | 49 | if path is not None: 50 | 51 | # save serialized function IR 52 | tr.storage.to_file(path) 53 | 54 | print '%d instructions saved to %s' % (len(insn_list), path) 55 | 56 | else: 57 | 58 | # print translated instructions 59 | print insn_list 60 | 61 | main(sys.argv) 62 | 63 | # 64 | # EoF 65 | # 66 | 67 | -------------------------------------------------------------------------------- /pyopenreil/src/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # get Python version and path 3 | PYTHON = python 4 | PYVERSION = $(shell $(PYTHON) -c "import sys; print(sys.version[ : 3])") 5 | PYEXT = $(shell $(PYTHON) -c "import sys; print 'pyd' if sys.platform == 'win32' else 'so'") 6 | 7 | include makefile.inc 8 | 9 | # get python libraries and headers directories 10 | INCDIR = $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc())") 11 | PLATINCDIR = $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_inc(plat_specific = True))") 12 | 13 | ../translator.$(PYEXT): translator.o ../../libopenreil/src/libopenreil.a 14 | $(CXX) $(CXXFLAGS) -pthread -shared -o $@ $^ -lpython$(PYVERSION) 15 | 16 | translator.o: translator.cpp translator.pyx libopenreil.pxd 17 | $(CXX) $(CXXFLAGS) -c -fPIC translator.cpp -I$(INCDIR) -I$(PLATINCDIR) -I../../libopenreil/include 18 | 19 | CYTHON = cython 20 | translator.cpp: translator.pyx 21 | $(CYTHON) --embed --cplus translator.pyx 22 | 23 | all: ../translator.$(PYEXT) 24 | 25 | clean: 26 | @rm *.o *.cpp ../translator.$(PYEXT) 27 | 28 | # get Python site-packages directory path 29 | LIBDIR = $(shell $(PYTHON) -c "from distutils import sysconfig; print(sysconfig.get_python_lib().replace(chr(92), chr(47)))") 30 | INSTALLDIR = $(LIBDIR)/pyopenreil 31 | 32 | install: 33 | -mkdir $(INSTALLDIR) 34 | -mkdir $(INSTALLDIR)/arch 35 | -mkdir $(INSTALLDIR)/utils 36 | -mkdir $(INSTALLDIR)/scripts 37 | cp ../translator.$(PYEXT) $(INSTALLDIR) 38 | cp ../*.py $(INSTALLDIR) 39 | cp ../arch/*.py $(INSTALLDIR)/arch 40 | cp ../utils/*.py $(INSTALLDIR)/utils 41 | cp ../scripts/*.py $(INSTALLDIR)/scripts 42 | -------------------------------------------------------------------------------- /pyopenreil/src/libopenreil.pxd: -------------------------------------------------------------------------------- 1 | 2 | DEF REIL_MAX_NAME_LEN = 15 3 | DEF REIL_ERROR = -1 4 | 5 | cdef extern from "libopenreil.h": 6 | 7 | cdef enum _reil_op_t: 8 | 9 | I_NONE, # no operation 10 | I_UNK, # unknown instruction 11 | I_JCC, # conditional jump 12 | I_STR, # store value to register 13 | I_STM, # store value to memory 14 | I_LDM, # load value from memory 15 | I_ADD, # addition 16 | I_SUB, # substraction 17 | I_NEG, # negation 18 | I_MUL, # multiplication 19 | I_DIV, # division 20 | I_MOD, # modulus 21 | I_SMUL, # signed multiplication 22 | I_SDIV, # signed division 23 | I_SMOD, # signed modulus 24 | I_SHL, # shift left 25 | I_SHR, # shift right 26 | I_AND, # binary and 27 | I_OR, # binary or 28 | I_XOR, # binary xor 29 | I_NOT, # binary not 30 | I_EQ, # equation 31 | I_LT # less than 32 | 33 | cdef enum _reil_type_t: 34 | 35 | A_NONE, 36 | A_REG, # target architecture registry operand 37 | A_TEMP, # temporary registry operand 38 | A_CONST, # immediate value 39 | A_LOC # jump location 40 | 41 | ctypedef unsigned long long reil_const_t 42 | ctypedef unsigned long long reil_addr_t 43 | ctypedef unsigned short reil_inum_t 44 | 45 | cdef enum _reil_size_t: U1, U8, U16, U32, U64 46 | 47 | cdef struct _reil_arg_t: 48 | 49 | _reil_type_t type 50 | _reil_size_t size 51 | reil_const_t val 52 | reil_inum_t inum 53 | char name[REIL_MAX_NAME_LEN] 54 | 55 | cdef struct _reil_raw_t: 56 | 57 | reil_addr_t addr # address of the original assembly instruction 58 | int size # ... and it's size 59 | unsigned char *data # pointer to the instruction bytes 60 | char *str_mnem # instruction mnemonic 61 | char *str_op # instruction operands 62 | 63 | cdef struct _reil_inst_t: 64 | 65 | _reil_raw_t raw_info 66 | reil_inum_t inum # number of the IR subinstruction 67 | _reil_op_t op # operation code 68 | _reil_arg_t a, b, c # arguments 69 | unsigned long long flags 70 | 71 | ctypedef void* reil_t 72 | ctypedef void* reil_inst_handler_t 73 | 74 | cdef enum _reil_arch_t: 75 | 76 | ARCH_X86, 77 | ARCH_ARM 78 | 79 | ctypedef _reil_arg_t reil_arg_t 80 | ctypedef _reil_inst_t reil_inst_t 81 | ctypedef _reil_arch_t reil_arch_t 82 | 83 | int reil_log_init(int mask, char *path) 84 | void reil_log_close() 85 | 86 | int reil_translate_insn(reil_t reil, reil_addr_t addr, unsigned char *buff, int len) 87 | reil_t reil_init(reil_arch_t arch, reil_inst_handler_t handler, void *context) 88 | void reil_close(reil_t reil) 89 | -------------------------------------------------------------------------------- /pyopenreil/src/translator.pyx: -------------------------------------------------------------------------------- 1 | cimport libopenreil 2 | 3 | ARCH_X86 = 0 4 | ARCH_ARM = 1 5 | 6 | # IR instruction attributes 7 | IATTR_ASM = 0 8 | IATTR_BIN = 1 9 | IATTR_FLAGS = 2 10 | 11 | # log_init() mask constants 12 | LOG_INFO = 0x00000001 # regular message 13 | LOG_WARN = 0x00000002 # error 14 | LOG_ERR = 0x00000004 # warning 15 | LOG_BIN = 0x00000008 # instruction bytes 16 | LOG_ASM = 0x00000010 # instruction assembly code 17 | LOG_VEX = 0x00000020 # instruction VEX code 18 | LOG_BIL = 0x00000040 # instruction BAP IL code 19 | 20 | # enable all debug messages 21 | LOG_ALL = 0x7FFFFFFF 22 | 23 | # disable all debug messages 24 | LOG_NONE = 0 25 | 26 | # default log messages mask 27 | LOG_MASK_DEFAULT = LOG_INFO | LOG_WARN | LOG_ERR 28 | 29 | cdef process_arg(libopenreil._reil_arg_t arg): 30 | 31 | # convert reil_arg_t to the python tuple 32 | if arg.type == libopenreil.A_NONE: 33 | 34 | return () 35 | 36 | elif arg.type == libopenreil.A_REG: 37 | 38 | return ( arg.type, arg.size, arg.name ) 39 | 40 | elif arg.type == libopenreil.A_TEMP: 41 | 42 | return ( arg.type, arg.size, arg.name ) 43 | 44 | elif arg.type == libopenreil.A_CONST: 45 | 46 | return ( arg.type, arg.size, arg.val ) 47 | 48 | elif arg.type == libopenreil.A_LOC: 49 | 50 | return ( arg.type, ( arg.val, arg.inum )) 51 | 52 | cdef int process_insn(libopenreil.reil_inst_t* inst, object context): 53 | 54 | attr = {} 55 | 56 | cdef unsigned char* data 57 | cdef char* str_mnem 58 | cdef char* str_op 59 | 60 | if inst.flags != 0: 61 | 62 | attr[IATTR_FLAGS] = inst.flags 63 | 64 | if inst.inum == 0: 65 | 66 | data = inst.raw_info.data 67 | str_mnem = inst.raw_info.str_mnem 68 | str_op = inst.raw_info.str_op 69 | 70 | if data != NULL: 71 | 72 | # instruction bytes 73 | attr[IATTR_BIN] = (data)[:inst.raw_info.size] 74 | 75 | if str_mnem != NULL and str_op != NULL: 76 | 77 | # assembly instruction 78 | attr[IATTR_ASM] = ( str(str_mnem), str(str_op) ) 79 | 80 | # convert reil_inst_t to the python tuple 81 | raw_info = ( inst.raw_info.addr, inst.raw_info.size ) 82 | args = ( process_arg(inst.a), process_arg(inst.b), process_arg(inst.c) ) 83 | 84 | # put instruction into the list 85 | context.insert(0, ( raw_info, inst.inum, inst.op, args, attr )) 86 | 87 | return 1 88 | 89 | 90 | class Error(Exception): 91 | 92 | def __init__(self, msg): 93 | 94 | self.msg = msg 95 | 96 | def __str__(self): 97 | 98 | return self.msg 99 | 100 | 101 | class InitError(Error): 102 | 103 | pass 104 | 105 | 106 | class TranslationError(Error): 107 | 108 | def __init__(self, addr): 109 | 110 | self.addr = addr 111 | 112 | def __str__(self): 113 | 114 | return 'Error while translating instruction %s to REIL' % hex(self.addr) 115 | 116 | 117 | cdef class Translator: 118 | 119 | cdef libopenreil.reil_t reil 120 | cdef libopenreil.reil_arch_t reil_arch 121 | cdef char* log_path 122 | translated = [] 123 | 124 | def __init__(self, arch, log_path = None, log_mask = LOG_MASK_DEFAULT): 125 | 126 | self.reil_arch = self.get_reil_arch(arch) 127 | 128 | if log_path is None: 129 | 130 | self.log_path = NULL 131 | 132 | else: 133 | 134 | self.log_path = log_path 135 | 136 | # initialize logging 137 | libopenreil.reil_log_init(log_mask, self.log_path) 138 | 139 | # initialize translator 140 | self.reil = libopenreil.reil_init(self.reil_arch, 141 | process_insn, self.translated) 142 | 143 | if self.reil == NULL: 144 | 145 | raise InitError('Error while initializing REIL translator') 146 | 147 | def __del__(self): 148 | 149 | libopenreil.reil_close(self.reil) 150 | libopenreil.reil_log_close() 151 | 152 | def get_reil_arch(self, arch): 153 | 154 | try: 155 | 156 | return { ARCH_X86: libopenreil.ARCH_X86, 157 | ARCH_ARM: libopenreil.ARCH_ARM }[ arch ] 158 | 159 | except KeyError: 160 | 161 | raise InitError('Unknown architecture') 162 | 163 | def to_reil(self, data, addr = 0): 164 | 165 | ret = [] 166 | cdef unsigned char* c_data = data 167 | cdef int c_size = len(data) 168 | 169 | # translate specified binary code 170 | num = libopenreil.reil_translate_insn(self.reil, addr, c_data, c_size) 171 | if num == -1: 172 | 173 | raise TranslationError(addr) 174 | 175 | # collect translated instructions 176 | while len(self.translated) > 0: ret.append(self.translated.pop()) 177 | return ret 178 | 179 | -------------------------------------------------------------------------------- /pyopenreil/utils/GDB.py: -------------------------------------------------------------------------------- 1 | from pyopenreil import REIL 2 | 3 | class Reader(REIL.Reader): 4 | 5 | def __init__(self, arch, inferior): 6 | 7 | self.arch = arch 8 | self.inferior = inferior 9 | 10 | super(REIL.Reader, self).__init__() 11 | 12 | def read(self, addr, size): 13 | 14 | return str(self.inferior.read_memory(addr, size)) 15 | 16 | def read_insn(self, addr): 17 | 18 | return self.read(addr, REIL.MAX_INST_LEN) 19 | 20 | # 21 | # EoF 22 | # 23 | -------------------------------------------------------------------------------- /pyopenreil/utils/IDA.py: -------------------------------------------------------------------------------- 1 | from pyopenreil import REIL 2 | import idc 3 | 4 | class Reader(REIL.Reader): 5 | 6 | def __init__(self, arch): 7 | 8 | self.arch = arch 9 | 10 | def read(self, addr, size): 11 | 12 | return idc.GetManyBytes(addr, size) 13 | 14 | def read_insn(self, addr): 15 | 16 | return self.read(addr, idc.ItemSize(addr)) 17 | 18 | # 19 | # EoF 20 | # 21 | -------------------------------------------------------------------------------- /pyopenreil/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/pyopenreil/utils/__init__.py -------------------------------------------------------------------------------- /pyopenreil/utils/bin_BFD.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | import pybfd.bfd 3 | 4 | file_dir = os.path.abspath(os.path.dirname(__file__)) 5 | test_dir = os.path.abspath(os.path.join(file_dir, '..', '..', 'tests')) 6 | 7 | from pyopenreil import REIL 8 | 9 | class Reader(REIL.Reader): 10 | 11 | def __init__(self, path, arch = None): 12 | 13 | # load image 14 | self.bfd = pybfd.bfd.Bfd(path) 15 | self.arch = arch 16 | 17 | if self.arch is None: 18 | 19 | if self.bfd.architecture == 0: 20 | 21 | # because bfd is piece of shit 22 | raise Exception('Unknown bfd architecture, you also may try to specify it manually') 23 | 24 | try: 25 | 26 | # get REIL arch by file arch 27 | # FIXME: check for arm as well 28 | self.arch = { pybfd.bfd.ARCH_I386: REIL.ARCH_X86 }[ self.bfd.architecture ] 29 | 30 | except KeyError: 31 | 32 | raise Exception('Unsupported architecture %s' % self.bfd.architecture_name) 33 | 34 | super(REIL.Reader, self).__init__() 35 | 36 | def read(self, addr, size): 37 | 38 | for sec in self.bfd.sections.values(): 39 | 40 | # lookup for image section by address 41 | if addr >= sec.vma and addr < sec.vma + sec.size: 42 | 43 | # return section data 44 | addr -= sec.vma 45 | return sec.content[addr : addr + size] 46 | 47 | # invalid VA 48 | print 'Reader.read(): Address 0x%x is outside of executable image' % addr 49 | raise REIL.ReadError(addr) 50 | 51 | def read_insn(self, addr): 52 | 53 | return self.read(addr, REIL.MAX_INST_LEN) 54 | 55 | 56 | class TestBFD(unittest.TestCase): 57 | 58 | BIN_PATH = os.path.join(test_dir, 'fib') 59 | PROC_ADDR = 0x08048434 60 | 61 | def test_reader(self): 62 | 63 | if os.path.isfile(self.BIN_PATH): 64 | 65 | reader = Reader(self.BIN_PATH) 66 | tr = REIL.CodeStorageTranslator(reader) 67 | 68 | print tr.get_func(self.PROC_ADDR) 69 | 70 | # 71 | # EoF 72 | # 73 | -------------------------------------------------------------------------------- /pyopenreil/utils/bin_PE.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | import pefile 3 | 4 | file_dir = os.path.abspath(os.path.dirname(__file__)) 5 | test_dir = os.path.abspath(os.path.join(file_dir, '..', '..', 'tests')) 6 | 7 | from pyopenreil import REIL 8 | 9 | class Reader(REIL.Reader): 10 | 11 | def __init__(self, path): 12 | 13 | # load PE image 14 | self.pe = pefile.PE(path, fast_load = True) 15 | 16 | try: 17 | 18 | # get REIL arch by file arch 19 | machine = self.pe.FILE_HEADER.Machine 20 | machine = pefile.MACHINE_TYPE[machine] 21 | 22 | self.arch = { 'IMAGE_FILE_MACHINE_I386': REIL.ARCH_X86 }[ machine ] 23 | 24 | except KeyError: 25 | 26 | raise Exception('Unsupported architecture') 27 | 28 | super(REIL.Reader, self).__init__() 29 | 30 | def read(self, addr, size): 31 | 32 | if addr < self.pe.OPTIONAL_HEADER.ImageBase or \ 33 | addr > self.pe.OPTIONAL_HEADER.ImageBase + self.pe.OPTIONAL_HEADER.SizeOfImage: 34 | 35 | # invalid VA 36 | print 'Reader.read(): Address 0x%x is outside of executable image' % addr 37 | raise REIL.ReadError(addr) 38 | 39 | # convert VA to RVA 40 | addr -= self.pe.OPTIONAL_HEADER.ImageBase 41 | 42 | try: 43 | 44 | return self.pe.get_data(rva = addr, length = size) 45 | 46 | except e, why: 47 | 48 | print 'Reader.read(): Exception:', str(why) 49 | raise REIL.ReadError(addr) 50 | 51 | def read_insn(self, addr): 52 | 53 | return self.read(addr, REIL.MAX_INST_LEN) 54 | 55 | 56 | class TestPE(unittest.TestCase): 57 | 58 | BIN_PATH = os.path.join(test_dir, 'fib.exe') 59 | PROC_ADDR = 0x004016B0 60 | 61 | def test_reader(self): 62 | 63 | if os.path.isfile(self.BIN_PATH): 64 | 65 | reader = Reader(self.BIN_PATH) 66 | tr = REIL.CodeStorageTranslator(reader) 67 | 68 | print tr.get_func(self.PROC_ADDR) 69 | 70 | # 71 | # EoF 72 | # 73 | -------------------------------------------------------------------------------- /pyopenreil/utils/kd.py: -------------------------------------------------------------------------------- 1 | from pyopenreil import REIL 2 | import pykd 3 | 4 | class Reader(REIL.Reader): 5 | 6 | def __init__(self, arch): 7 | 8 | self.arch = arch 9 | 10 | def read(self, addr, size): 11 | 12 | return pykd.loadChars(addr, size) 13 | 14 | def read_insn(self, addr): 15 | 16 | return self.read(addr, REIL.MAX_INST_LEN) 17 | 18 | # 19 | # EoF 20 | # 21 | -------------------------------------------------------------------------------- /pyopenreil/utils/mongodb.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import pymongo 3 | from pyopenreil import REIL 4 | from cachetools import LRUCache 5 | 6 | _U64IN = lambda v: -(0xFFFFFFFFFFFFFFFFL + 1L - v) if v > 0x7FFFFFFFFFFFFFFFL else v 7 | 8 | _U64OUT = lambda v: (0xFFFFFFFFFFFFFFFFL + 1L + v) if v < 0 else v 9 | 10 | class CodeStorageMongo(REIL.CodeStorageMem): 11 | 12 | # mongodb host 13 | DEF_HOST = '127.0.0.1' 14 | DEF_PORT = 27017 15 | 16 | # defult database name 17 | DEF_DB = 'openreil' 18 | 19 | # index for instructions collection 20 | INDEX = [('addr', pymongo.ASCENDING), ('inum', pymongo.ASCENDING)] 21 | 22 | CACHE_SIZE = 1024 23 | 24 | def __init__(self, arch, collection, db = None, host = None, port = None): 25 | 26 | self.arch = arch 27 | self.db_name = self.DEF_DB if db is None else db 28 | self.collection_name = collection 29 | 30 | self.host = self.DEF_HOST if host is None else host 31 | self.port = self.DEF_PORT if port is None else port 32 | 33 | # instructions cache 34 | self.cache = LRUCache(maxsize = self.CACHE_SIZE) 35 | 36 | # connect to the server 37 | self.client = pymongo.Connection(self.host, self.port) 38 | self.db = self.client[self.db_name] 39 | 40 | # get collection 41 | self.collection = self.db[self.collection_name] 42 | self.collection.ensure_index(self.INDEX) 43 | 44 | def __iter__(self): 45 | 46 | for item in self.collection.find().sort(self.INDEX): 47 | 48 | yield REIL.Insn(self._insn_from_item(item)) 49 | 50 | def _insn_to_item(self, insn): 51 | 52 | insn = REIL.Insn(insn) 53 | 54 | def _arg_in(arg): 55 | 56 | if arg.type == REIL.A_NONE: 57 | 58 | return () 59 | 60 | elif arg.type == REIL.A_CONST: 61 | 62 | return ( arg.type, arg.size, _U64IN(arg.val) ) 63 | 64 | else: 65 | 66 | return ( arg.type, arg.size, arg.name ) 67 | 68 | if insn.has_attr(REIL.IATTR_BIN): 69 | 70 | # JSON doesn't support binary data 71 | insn.set_attr(REIL.IATTR_BIN, base64.b64encode(insn.get_attr(REIL.IATTR_BIN))) 72 | 73 | # JSON doesn't support numeric keys 74 | attr = [ (key, val) for key, val in insn.attr.items() ] 75 | 76 | return { 77 | 78 | 'addr': _U64IN(insn.addr), 'size': insn.size, 'inum': insn.inum, 'op': insn.op, \ 79 | 'a': _arg_in(insn.a), 'b': _arg_in(insn.b), 'c': _arg_in(insn.c), \ 80 | 'attr': attr 81 | } 82 | 83 | def _insn_from_item(self, item): 84 | 85 | attr, attr_dict = item['attr'], {} 86 | 87 | def _arg_out(arg): 88 | 89 | if len(arg) == 0: 90 | 91 | return () 92 | 93 | elif REIL.Arg_type(arg) == REIL.A_CONST: 94 | 95 | arg = ( REIL.Arg_type(arg), REIL.Arg_size(arg), _U64OUT(REIL.Arg_val(arg)) ) 96 | 97 | return arg 98 | 99 | for key, val in attr: 100 | 101 | attr_dict[key] = val 102 | 103 | if attr_dict.has_key(REIL.IATTR_BIN): 104 | 105 | # get instruction binary data from base64 106 | attr_dict[REIL.IATTR_BIN] = base64.b64decode(attr_dict[REIL.IATTR_BIN]) 107 | 108 | return ( 109 | 110 | ( _U64OUT(item['addr']), item['size'] ), item['inum'], item['op'], \ 111 | ( _arg_out(item['a']), _arg_out(item['b']), _arg_out(item['c']) ), \ 112 | attr_dict 113 | ) 114 | 115 | def _get_key(self, ir_addr): 116 | 117 | return { 'addr': ir_addr[0], 'inum': ir_addr[1] } 118 | 119 | def _find(self, ir_addr): 120 | 121 | return self.collection.find_one(self._get_key(ir_addr)) 122 | 123 | def _get_insn(self, ir_addr): 124 | 125 | # get item from cache 126 | try: return self.cache[ir_addr] 127 | except KeyError: pass 128 | 129 | # get item from collection 130 | insn = self._find(ir_addr) 131 | if insn is not None: 132 | 133 | insn = self._insn_from_item(insn) 134 | 135 | # update cache 136 | self.cache[ir_addr] = insn 137 | 138 | return insn 139 | 140 | else: 141 | 142 | raise REIL.StorageError(*ir_addr) 143 | 144 | def _del_insn(self, ir_addr): 145 | 146 | insn = self._find(ir_addr) 147 | if insn is not None: 148 | 149 | # remove item from collection 150 | self.collection.remove(self._get_key(ir_addr)) 151 | 152 | # remove item from cache 153 | try: del self.cache[ir_addr] 154 | except KeyError: pass 155 | 156 | else: 157 | 158 | raise REIL.StorageError(*ir_addr) 159 | 160 | def _put_insn(self, insn): 161 | 162 | ir_addr = REIL.Insn_ir_addr(insn) 163 | 164 | if self._find(ir_addr) is not None: 165 | 166 | # update existing item 167 | self.collection.update(self._get_key(ir_addr), self._insn_to_item(insn)) 168 | 169 | else: 170 | 171 | # add a new item 172 | self.collection.insert(self._insn_to_item(insn)) 173 | 174 | # update cache 175 | self.cache[ir_addr] = insn 176 | 177 | def size(self): 178 | 179 | return self.collection.find().count() 180 | 181 | def clear(self): 182 | 183 | self.cache.clear() 184 | 185 | # remove all items of collection 186 | return self.collection.remove() 187 | 188 | 189 | # 190 | # EoF 191 | # 192 | -------------------------------------------------------------------------------- /tests/fib.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // computes a number of fibbonnaci sequence 5 | int fib(int n) 6 | { 7 | int result = 1, prev = 0; 8 | 9 | while (n > 0) 10 | { 11 | int current = result; 12 | 13 | result += prev; 14 | prev = current; 15 | 16 | n -= 1; 17 | } 18 | 19 | return result; 20 | } 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | int n = 0, val = 0; 25 | 26 | if (argc < 2) 27 | { 28 | return -1; 29 | } 30 | 31 | n = atoi(argv[1]); 32 | val = fib(n); 33 | 34 | printf("%d number in Fibonacci sequence is %d\n", n, val); 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /tests/fib_arm.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/fib_arm.elf -------------------------------------------------------------------------------- /tests/fib_x86.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/fib_x86.elf -------------------------------------------------------------------------------- /tests/fib_x86.pe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/fib_x86.pe -------------------------------------------------------------------------------- /tests/md5_arm.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/md5_arm.elf -------------------------------------------------------------------------------- /tests/md5_x86.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/md5_x86.elf -------------------------------------------------------------------------------- /tests/md5_x86.pe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/md5_x86.pe -------------------------------------------------------------------------------- /tests/rc4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 5 | 6 | typedef struct _RC4_CTX 7 | { 8 | unsigned char S[256]; 9 | unsigned char x, y; 10 | 11 | } RC4_CTX; 12 | 13 | void rc4_swap(unsigned char *a, unsigned char *b) 14 | { 15 | unsigned char c = *a; 16 | 17 | *a = *b; 18 | *b = c; 19 | } 20 | 21 | void rc4_set_key(RC4_CTX *ctx, unsigned char *key, int key_len) 22 | { 23 | int i = 0; 24 | unsigned char x = 0, y = 0; 25 | unsigned char *S = ctx->S; 26 | 27 | ctx->x = x = 0; 28 | ctx->y = y = 0; 29 | 30 | for (i = 0; i < 256; i++) 31 | { 32 | S[i] = (unsigned char)i; 33 | } 34 | 35 | for (i = 0; i < 256; i++) 36 | { 37 | y = (y + S[i] + key[x]) & 0xff; 38 | 39 | rc4_swap(&S[i], &S[y]); 40 | 41 | if (++x >= key_len) 42 | { 43 | x = 0; 44 | } 45 | } 46 | } 47 | 48 | void rc4_crypt(RC4_CTX *ctx, unsigned char *data, int data_len) 49 | { 50 | int i = 0; 51 | unsigned char x = 0, y = 0; 52 | unsigned char *S = ctx->S; 53 | 54 | for (i = 0; i < data_len; i++) 55 | { 56 | x = (x + 1) & 0xff; 57 | y = (y + S[x]) & 0xff; 58 | 59 | rc4_swap(&S[x], &S[y]); 60 | 61 | data[i] ^= S[(S[x] + S[y]) & 0xff]; 62 | } 63 | 64 | ctx->x = x; 65 | ctx->y = y; 66 | } 67 | 68 | #define MAX_DATA_LEN 255 69 | 70 | RC4_CTX m_ctx; 71 | 72 | int main(int argc, char *argv[]) 73 | { 74 | if (argc < 3) 75 | { 76 | return -1; 77 | } 78 | 79 | int i = 0; 80 | unsigned char buff[MAX_DATA_LEN]; 81 | char *key = argv[1], *data = argv[2]; 82 | int key_len = strlen(key); 83 | int data_len = strlen(data); 84 | 85 | memcpy(buff, data, MIN(MAX_DATA_LEN, data_len)); 86 | 87 | printf("\nKey: "); 88 | 89 | for (i = 0; i < key_len; i++) 90 | { 91 | printf("%.2x ", (unsigned char)key[i]); 92 | } 93 | 94 | printf("\n\nPlaintext: "); 95 | 96 | for (i = 0; i < data_len; i++) 97 | { 98 | printf("%.2x ", buff[i]); 99 | } 100 | 101 | // encrypt 102 | rc4_set_key(&m_ctx, (unsigned char *)key, key_len); 103 | rc4_crypt(&m_ctx, buff, data_len); 104 | 105 | printf("\n\nEncrypted: "); 106 | 107 | for (i = 0; i < data_len; i++) 108 | { 109 | printf("%.2x ", buff[i]); 110 | } 111 | 112 | // decrypt 113 | rc4_set_key(&m_ctx, (unsigned char *)key, key_len); 114 | rc4_crypt(&m_ctx, buff, data_len); 115 | 116 | printf("\n\nDecrypted: "); 117 | 118 | for (i = 0; i < data_len; i++) 119 | { 120 | printf("%.2x ", buff[i]); 121 | } 122 | 123 | printf("\n\n"); 124 | 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /tests/rc4_arm.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/rc4_arm.elf -------------------------------------------------------------------------------- /tests/rc4_x86.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/rc4_x86.elf -------------------------------------------------------------------------------- /tests/rc4_x86.pe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/rc4_x86.pe -------------------------------------------------------------------------------- /tests/run_unittest.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | from subprocess import * 3 | 4 | file_dir = os.path.abspath(os.path.dirname(__file__)) 5 | reil_dir = os.path.abspath(os.path.join(file_dir, '..')) 6 | if not reil_dir in sys.path: sys.path = [ reil_dir ] + sys.path 7 | 8 | from pyopenreil.REIL import * 9 | from pyopenreil.VM import * 10 | 11 | try: 12 | 13 | # check for pefile module (required for loading test PE binaries) 14 | import pefile 15 | from pyopenreil.utils.bin_PE import * 16 | 17 | # check for Z3 module (required for test_kao.py) 18 | import z3 19 | 20 | # load unit tests that depends on Z3 21 | from test_kao import TestKao 22 | 23 | except ImportError, why: print '[!]', str(why) 24 | 25 | try: 26 | 27 | # check for BFD python module (required for loading ELF binaries) 28 | import pybfd 29 | 30 | # load unit tests that depends on pybfd 31 | from pyopenreil.utils.bin_BFD import * 32 | 33 | except ImportError, why: print '[!]', str(why) 34 | 35 | # load .c unit tests 36 | from test_fib import * 37 | from test_rc4 import * 38 | from test_md5 import * 39 | 40 | def check_program(command, code = 0): 41 | 42 | try: 43 | 44 | p = Popen(command, stdout = PIPE, stderr = PIPE) 45 | stdout, stderr = p.communicate() 46 | 47 | p.stdout.close() 48 | p.stderr.close() 49 | 50 | if p.returncode != code: 51 | 52 | raise OSError('Process returned %d' % p.returncode) 53 | 54 | return True 55 | 56 | except OSError, why: 57 | 58 | print str(why) 59 | print 'Error while executing "%s"' % command[0] 60 | return False 61 | 62 | def check_nasm(): 63 | 64 | from pyopenreil.utils import asm 65 | 66 | return check_program([ asm.CompilerNasm.nasm_path, '-h' ]) 67 | 68 | def check_objcopy(): 69 | 70 | return check_program([ 'objcopy', '--help' ]) 71 | 72 | def check_otool(): 73 | 74 | return check_program([ 'otool' ], code = 1) 75 | 76 | def check_numpy(): 77 | 78 | try: 79 | 80 | import numpy 81 | return True 82 | 83 | except ImportError, why: 84 | 85 | print str(why) 86 | print 'check_numpy(): Error while loading numpy' 87 | return False 88 | 89 | def main(): 90 | 91 | ok = True 92 | 93 | # check for required programs and modules 94 | if not check_numpy(): ok = False 95 | 96 | if sys.platform == 'darwin': 97 | 98 | ok = check_otool() 99 | 100 | else: 101 | 102 | og = check_objcopy() 103 | 104 | if ok: 105 | 106 | unittest.main(verbosity = 2) 107 | 108 | else: 109 | 110 | print 'Unable to run tests, check for installed as, objcopy/otool and python-numpy' 111 | 112 | if __name__ == '__main__': 113 | 114 | main() 115 | 116 | # 117 | # EoF 118 | # 119 | 120 | -------------------------------------------------------------------------------- /tests/test_fib.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | 3 | from pyopenreil.REIL import * 4 | from pyopenreil.VM import * 5 | 6 | class TestFib(unittest.TestCase): 7 | 8 | CPU_DEBUG = 0 9 | FILE_DIR = os.path.abspath(os.path.dirname(__file__)) 10 | 11 | is_linux = lambda self: 'linux' in sys.platform 12 | file_path = lambda self, path: os.path.join(self.FILE_DIR, path) 13 | 14 | def _run_test(self, callfunc, arch, reader, addr): 15 | 16 | # load executable image of the test program 17 | tr = CodeStorageTranslator(reader) 18 | 19 | # construct dataflow graph for given function 20 | dfg = DFGraphBuilder(tr).traverse(addr) 21 | insn_before = tr.size() 22 | 23 | # run some basic optimizations 24 | dfg.optimize_all(storage = tr.storage) 25 | insn_after = tr.size() 26 | 27 | print tr.storage 28 | 29 | print '%d instructions before optimization and %d after\n' % \ 30 | (insn_before, insn_after) 31 | 32 | # create CPU and ABI 33 | cpu = Cpu(arch, debug = self.CPU_DEBUG) 34 | abi = Abi(cpu, tr) 35 | 36 | testval = 11 37 | 38 | # int fib(int n); 39 | ret = callfunc(abi)(addr, testval) 40 | cpu.dump() 41 | 42 | print '%d number in Fibonacci sequence is %d' % (testval + 1, ret) 43 | 44 | assert ret == 144 45 | 46 | 47 | class TestFib_X86(TestFib): 48 | 49 | ELF_NAME = 'fib_x86.elf' 50 | ELF_ADDR = 0x08048414 51 | 52 | PE_NAME = 'fib_x86.pe' 53 | PE_ADDR = 0x004016B0 54 | 55 | def test_elf(self): 56 | 57 | # BFD available for different operating systems 58 | # but current test needs Linux. 59 | if not self.is_linux(): return 60 | 61 | try: 62 | 63 | from pyopenreil.utils import bin_BFD 64 | 65 | self._run_test(lambda abi: abi.cdecl, 66 | ARCH_X86, bin_BFD.Reader(self.file_path(self.ELF_NAME)), self.ELF_ADDR) 67 | 68 | except ImportError, why: print '[!]', str(why) 69 | 70 | def test_pe(self): 71 | 72 | try: 73 | 74 | from pyopenreil.utils import bin_PE 75 | 76 | self._run_test(lambda abi: abi.cdecl, 77 | ARCH_X86, bin_PE.Reader(self.file_path(self.PE_NAME)), self.PE_ADDR) 78 | 79 | except ImportError, why: print '[!]', str(why) 80 | 81 | 82 | class TestFib_ARM(TestFib): 83 | 84 | ELF_NAME = 'fib_arm.elf' 85 | ELF_ADDR = arm_thumb(0x000083a1) 86 | 87 | def test_elf(self): 88 | 89 | # BFD available for different operating systems 90 | # but current test needs Linux. 91 | if not self.is_linux(): return 92 | 93 | try: 94 | 95 | from pyopenreil.utils import bin_BFD 96 | 97 | self._run_test(lambda abi: abi.arm_call, 98 | ARCH_ARM, bin_BFD.Reader(self.file_path(self.ELF_NAME), arch = ARCH_ARM), 99 | self.ELF_ADDR) 100 | 101 | except ImportError, why: print '[!]', str(why) 102 | 103 | # 104 | # EoF 105 | # 106 | -------------------------------------------------------------------------------- /tests/test_md5.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | import md5 3 | 4 | from pyopenreil.REIL import * 5 | from pyopenreil.VM import * 6 | 7 | class TestMD5(unittest.TestCase): 8 | 9 | CPU_DEBUG = 0 10 | FILE_DIR = os.path.abspath(os.path.dirname(__file__)) 11 | 12 | is_linux = lambda self: 'linux' in sys.platform 13 | file_path = lambda self, path: os.path.join(self.FILE_DIR, path) 14 | 15 | def _run_test(self, callfunc, arch, reader, addr_list): 16 | 17 | md5_init, md5_append, md5_finish = addr_list 18 | 19 | # test input for MD5 hashing 20 | test_val = 'foobar' 21 | digest_len = 16 22 | 23 | # load executable image of the test program 24 | tr = CodeStorageTranslator(reader) 25 | 26 | # run some basic optimizations 27 | tr.optimize(addr_list) 28 | 29 | print tr.storage 30 | 31 | # create CPU and ABI 32 | cpu = Cpu(arch, debug = self.CPU_DEBUG) 33 | abi = Abi(cpu, tr) 34 | 35 | ctx = abi.buff(6 * 4 + 8 + 64) 36 | val = abi.buff(test_val) 37 | digest = abi.buff(digest_len) 38 | 39 | # void md5_init(md5_state_t *) 40 | callfunc(abi)(md5_init, ctx) 41 | 42 | # void md5_append(md5_state_t *, const md5_byte_t *, int) 43 | callfunc(abi)(md5_append, ctx, val, len(test_val)) 44 | 45 | # md5_finish(md5_state_t *, md5_byte_t *) 46 | callfunc(abi)(md5_finish, ctx, digest) 47 | 48 | # read results of hash function 49 | digest = abi.read(digest, digest_len) 50 | print 'Hash value:', ''.join(map(lambda b: '%.2x' % ord(b), digest)) 51 | 52 | # check for correct result 53 | assert digest == md5.new(test_val).digest() 54 | 55 | 56 | class TestMD5_X86(TestMD5): 57 | 58 | ELF_NAME = 'md5_x86.elf' 59 | ELF_ADDR = ( 0x08049254, 0x08049296, 0x080493C2 ) 60 | 61 | PE_NAME = 'md5_x86.pe' 62 | PE_ADDR = ( 0x00402417, 0x00402459, 0x00402585 ) 63 | 64 | def test_elf(self): 65 | 66 | # BFD available for different operating systems 67 | # but current test needs Linux. 68 | if not self.is_linux(): return 69 | 70 | try: 71 | 72 | from pyopenreil.utils import bin_BFD 73 | 74 | self._run_test(lambda abi: abi.cdecl, 75 | ARCH_X86, bin_BFD.Reader(self.file_path(self.ELF_NAME)), self.ELF_ADDR) 76 | 77 | except ImportError, why: print '[!]', str(why) 78 | 79 | def test_pe(self): 80 | 81 | try: 82 | 83 | from pyopenreil.utils import bin_PE 84 | 85 | self._run_test(lambda abi: abi.cdecl, 86 | ARCH_X86, bin_PE.Reader(self.file_path(self.PE_NAME)), self.PE_ADDR) 87 | 88 | except ImportError, why: print '[!]', str(why) 89 | 90 | 91 | class TestMD5_ARM(TestMD5): 92 | 93 | ELF_NAME = 'md5_arm.elf' 94 | ELF_ADDR = ( 0x00009AE0, 0x00009B58, 0x00009D1C ) 95 | 96 | def test_elf(self): 97 | 98 | # BFD available for different operating systems 99 | # but current test needs Linux. 100 | if not self.is_linux(): return 101 | 102 | try: 103 | 104 | from pyopenreil.utils import bin_BFD 105 | 106 | self._run_test(lambda abi: abi.arm_call, 107 | ARCH_ARM, bin_BFD.Reader(self.file_path(self.ELF_NAME), arch = ARCH_ARM), 108 | self.ELF_ADDR) 109 | 110 | except ImportError, why: print '[!]', str(why) 111 | 112 | # 113 | # EoF 114 | # 115 | -------------------------------------------------------------------------------- /tests/test_rc4.py: -------------------------------------------------------------------------------- 1 | import sys, os, unittest 2 | 3 | from pyopenreil.REIL import * 4 | from pyopenreil.VM import * 5 | 6 | class TestRC4(unittest.TestCase): 7 | 8 | CPU_DEBUG = 0 9 | FILE_DIR = os.path.abspath(os.path.dirname(__file__)) 10 | 11 | is_linux = lambda self: 'linux' in sys.platform 12 | file_path = lambda self, path: os.path.join(self.FILE_DIR, path) 13 | 14 | def _run_test(self, callfunc, arch, reader, addr_list): 15 | 16 | rc4_set_key, rc4_crypt = addr_list 17 | 18 | # test input data for RC4 encryption 19 | test_key = 'somekey' 20 | test_val = 'bar' 21 | 22 | tr = CodeStorageTranslator(reader) 23 | 24 | # run some basic optimizations 25 | tr.optimize(addr_list) 26 | 27 | # create CPU and ABI 28 | cpu = Cpu(arch, debug = self.CPU_DEBUG) 29 | abi = Abi(cpu, tr) 30 | 31 | # allocate buffers for arguments of emulated functions 32 | ctx = abi.buff(256 + 4 * 2) 33 | val = abi.buff(test_val) 34 | 35 | # emulate rc4_set_key() function call 36 | callfunc(abi)(rc4_set_key, ctx, test_key, len(test_key)) 37 | 38 | # emulate rc4_crypt() function call 39 | callfunc(abi)(rc4_crypt, ctx, val, len(test_val)) 40 | 41 | # read results of RC4 encryption 42 | val = abi.read(val, len(test_val)) 43 | print 'Encrypted value:', repr(val) 44 | 45 | # check for correct result 46 | assert val == '\x38\x88\xBC' 47 | 48 | 49 | class TestRC4_X86(TestRC4): 50 | 51 | ELF_NAME = 'rc4_x86.elf' 52 | ELF_ADDR = ( 0x08048522, 0x080485EB ) 53 | 54 | PE_NAME = 'rc4_x86.pe' 55 | PE_ADDR = ( 0x004016D5, 0x004017B5 ) 56 | 57 | def test_elf(self): 58 | 59 | # BFD available for different operating systems 60 | # but current test needs Linux. 61 | if not self.is_linux(): return 62 | 63 | try: 64 | 65 | from pyopenreil.utils import bin_BFD 66 | 67 | self._run_test(lambda abi: abi.cdecl, 68 | ARCH_X86, bin_BFD.Reader(self.file_path(self.ELF_NAME)), self.ELF_ADDR) 69 | 70 | except ImportError, why: print '[!]', str(why) 71 | 72 | def test_pe(self): 73 | 74 | try: 75 | 76 | from pyopenreil.utils import bin_PE 77 | 78 | self._run_test(lambda abi: abi.cdecl, 79 | ARCH_X86, bin_PE.Reader(self.file_path(self.PE_NAME)), self.PE_ADDR) 80 | 81 | except ImportError, why: print '[!]', str(why) 82 | 83 | 84 | class TestRC4_ARM(TestRC4): 85 | 86 | ELF_NAME = 'rc4_arm.elf' 87 | ELF_ADDR = ( 0x000085B8, 0x000086FC ) 88 | 89 | def test_elf(self): 90 | 91 | # BFD available for different operating systems 92 | # but current test needs Linux. 93 | if not self.is_linux(): return 94 | 95 | try: 96 | 97 | from pyopenreil.utils import bin_BFD 98 | 99 | self._run_test(lambda abi: abi.arm_call, 100 | ARCH_ARM, bin_BFD.Reader(self.file_path(self.ELF_NAME), arch = ARCH_ARM), 101 | self.ELF_ADDR) 102 | 103 | except ImportError, why: print '[!]', str(why) 104 | 105 | # 106 | # EoF 107 | # 108 | -------------------------------------------------------------------------------- /tests/toyproject.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cr4sh/openreil/61fc2bf70ec219d46c337e336aa8239c7069ddbc/tests/toyproject.exe --------------------------------------------------------------------------------