16d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh#!/usr/bin/python
26d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
36d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh# Simple benchmark for Capstone by disassembling random code. By Nguyen Anh Quynh, 2014
4f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# Syntax:
5f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py          --> Benchmark all archs
6f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py x86      --> Benchmark all X86 (all 16bit, 32bit, 64bit)
7f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py x86-32   --> Benchmark X86-32 arch only
8f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py arm      --> Benchmark all ARM (arm, thumb)
9f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py aarch64  --> Benchmark ARM-64
10f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py mips     --> Benchmark all Mips (32bit, 64bit)
11f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh# ./suite/benchmark.py ppc      --> Benchmark PPC
126d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
136d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynhfrom capstone import *
146d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
156d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynhfrom time import time
166d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynhfrom random import randint
17f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynhimport sys
186d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
196d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
2034474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh# file providing code to disassemble
2134474f898989c11864e9d252544dd43c70549f13Nguyen Anh QuynhFILE = '/usr/bin/python'
226d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
2334474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
24783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynhall_tests = (
2507b20378163635cd0292244765f0b6e7ff992b6fNguyen Anh Quynh        (CS_ARCH_X86, CS_MODE_16, "X86-16 (Intel syntax)", 0),
2607b20378163635cd0292244765f0b6e7ff992b6fNguyen Anh Quynh        (CS_ARCH_X86, CS_MODE_32, "X86-32 (ATT syntax)", CS_OPT_SYNTAX_ATT),
27f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        (CS_ARCH_X86, CS_MODE_32, "X86-32 (Intel syntax)", 0),
28f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        (CS_ARCH_X86, CS_MODE_64, "X86-64 (Intel syntax)", 0),
29783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        (CS_ARCH_ARM, CS_MODE_ARM, "ARM", 0),
30f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        (CS_ARCH_ARM, CS_MODE_THUMB, "THUMB (ARM)", 0),
31d83c8c7d44af25a2ef5f7a0c1af0b2869c7acb67Nguyen Anh Quynh        (CS_ARCH_MIPS, CS_MODE_MIPS32 + CS_MODE_BIG_ENDIAN, "MIPS-32 (Big-endian)", 0),
32d83c8c7d44af25a2ef5f7a0c1af0b2869c7acb67Nguyen Anh Quynh        (CS_ARCH_MIPS, CS_MODE_MIPS64 + CS_MODE_LITTLE_ENDIAN, "MIPS-64-EL (Little-endian)", 0),
33f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        (CS_ARCH_ARM64, CS_MODE_ARM, "ARM-64 (AArch64)", 0),
3407b20378163635cd0292244765f0b6e7ff992b6fNguyen Anh Quynh        (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, "PPC", 0),
3507b20378163635cd0292244765f0b6e7ff992b6fNguyen Anh Quynh        (CS_ARCH_PPC, CS_MODE_BIG_ENDIAN, "PPC, print register with number only", CS_OPT_SYNTAX_NOREGNAME),
3661b7a722c10a71beacdf68dc81bd714cf865b22dNguyen Anh Quynh        (CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN, "Sparc", 0),
3761aaabbba0198424c685ee5acc83107c0c3c394eNguyen Anh Quynh        (CS_ARCH_SYSZ, 0, "SystemZ", 0),
386a5cc570ccf38bb0e6b495ce587d67077245d82cNguyen Anh Quynh        (CS_ARCH_XCORE, 0, "XCore", 0),
39783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        )
40783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh
41783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh
4211b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh# for debugging
4311b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynhdef to_hex(s):
4411b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh    return " ".join("0x" + "{0:x}".format(ord(c)).zfill(2) for c in s) # <-- Python 3 is OK
4511b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh
4634474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynhdef get_code(f, size):
4734474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh    code = f.read(size)
4834474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh    if len(code) != size:  # reached end-of-file?
49783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        # then reset file position to begin-of-file
5034474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh        f.seek(0)
5134474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh        code = f.read(size)
5234474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
5334474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh    return code
5434474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
5534474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
5634474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynhdef cs(md, code):
5734474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh    insns = md.disasm(code, 0)
586d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh    # uncomment below line to speed up this function 200 times!
596d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh    # return
606d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh    for i in insns:
616d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh        if i.address == 0x100000:
626d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh            print i
636d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
6434474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
65d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynhdef cs_lite(md, code):
66d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh    insns = md.disasm_lite(code, 0)
67d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh    for (addr, size, mnem, ops) in insns:
68d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        if addr == 0x100000:
69d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            print i
70d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh
71d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh
7234474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynhcfile = open(FILE)
7334474f898989c11864e9d252544dd43c70549f13Nguyen Anh Quynh
74783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynhfor (arch, mode, comment, syntax) in all_tests:
75f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh    try:
76f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        request = sys.argv[1]
77f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        if not request in comment.lower():
78f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh            continue
79f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh    except:
80f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh        pass
81f48a879e314679617f4ebd881f2372985585925fNguyen Anh Quynh
82783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh    print("Platform: %s" %comment)
83783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh
84783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh    try:
85783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        md = Cs(arch, mode)
86321163bf348718350e74017ca34f5b2ae5edad69Nguyen Anh Quynh        #md.detail = True
87783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh
88783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        if syntax != 0:
89783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            md.syntax = syntax
906d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
91783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        # warm up few times
92783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        cfile.seek(0)
93783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        for i in xrange(3):
94783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            code = get_code(cfile, 128)
9511b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh            #print to_hex(code)
9611b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh            #print
97783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            cs(md, code)
983079ed61cb7fd56961a7d17eadcf2536af59cebaNguyen Anh Quynh
99783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        # start real benchmark
100783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        c_t = 0
101783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        for i in xrange(50000):
102783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            code = get_code(cfile, 128)
10311b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh            #print to_hex(code)
10411b05193ec27eb62d2f0d44807a692b31cd9c0ccNguyen Anh Quynh            #print
1056d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
106783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            t1 = time()
107783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            cs(md, code)
108783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh            c_t += time() - t1
1096d50dc3c266f4a1b7f517935b961cfb20602011bNguyen Anh Quynh
110d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        print "Benchmark - full obj:", c_t, "seconds"
111d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        print
112d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh
113d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        cfile.seek(0)
114d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        c_t = 0
115d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        for i in xrange(50000):
116d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            code = get_code(cfile, 128)
117d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            #print to_hex(code)
118d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            #print
119d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh
120d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            t1 = time()
121d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            cs_lite(md, code)
122d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh            c_t += time() - t1
123d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh
124d53c1651a09df8c53d8e6dbf9086b7c2428a0427Nguyen Anh Quynh        print "Benchmark - lite:", c_t, "seconds"
125783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        print
126783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh    except CsError as e:
127783e6c006c434e2ab1843d2693fa357cacfef484Nguyen Anh Quynh        print("ERROR: %s" %e)
128