diff --git a/bindings/go/keystone/keystone_const.go b/bindings/go/keystone/keystone_const.go
index 7768d1ad9b07d463a4ee30f15b80d313513186c7..7cf27ef5cf4bbcfb8f60d9a4fb1874fd72cc89c0 100644
--- a/bindings/go/keystone/keystone_const.go
+++ b/bindings/go/keystone/keystone_const.go
@@ -45,6 +45,7 @@ const (
 )
 
 const (
+	OPT_SYM_RESOLVER OptionValue = 2
 	OPT_SYNTAX_INTEL OptionValue = 1
 	OPT_SYNTAX_ATT OptionValue = 2
 	OPT_SYNTAX_NASM OptionValue = 4
diff --git a/bindings/nodejs/consts/keystone.js b/bindings/nodejs/consts/keystone.js
index a077580ffe7797dafa2715ff4650189c96eea34c..1b8a5f7ca79d306ff34923d74293b9381b7ac0a4 100644
--- a/bindings/nodejs/consts/keystone.js
+++ b/bindings/nodejs/consts/keystone.js
@@ -78,6 +78,7 @@ module.exports.ERR_ASM_INVALIDOPERAND = 512
 module.exports.ERR_ASM_MISSINGFEATURE = 513
 module.exports.ERR_ASM_MNEMONICFAIL = 514
 module.exports.OPT_SYNTAX = 1
+module.exports.OPT_SYM_RESOLVER = 2
 module.exports.OPT_SYNTAX_INTEL = 1
 module.exports.OPT_SYNTAX_ATT = 2
 module.exports.OPT_SYNTAX_NASM = 4
diff --git a/bindings/python/keystone/keystone.py b/bindings/python/keystone/keystone.py
index ee0e9e8edcd0e9c6e832156f0b600a4fb75a3bcb..c0e7de8efe63bf1f74a9b5f5289997b679f67126 100644
--- a/bindings/python/keystone/keystone.py
+++ b/bindings/python/keystone/keystone.py
@@ -91,11 +91,12 @@ _setup_prototype(_ks, "ks_open", kserr, c_uint, c_uint, POINTER(ks_engine))
 _setup_prototype(_ks, "ks_close", kserr, ks_engine)
 _setup_prototype(_ks, "ks_strerror", c_char_p, kserr)
 _setup_prototype(_ks, "ks_errno", kserr, ks_engine)
-_setup_prototype(_ks, "ks_option", kserr, ks_engine, c_int, c_size_t)
-# int ks_asm(ks_engine *ks, const char *string, uint64_t address, unsigned char **encoding, size_t *encoding_size, size_t *stat_count);
+_setup_prototype(_ks, "ks_option", kserr, ks_engine, c_int, c_void_p)
 _setup_prototype(_ks, "ks_asm", c_int, ks_engine, c_char_p, c_uint64, POINTER(POINTER(c_ubyte)), POINTER(c_size_t), POINTER(c_size_t))
 _setup_prototype(_ks, "ks_free", None, POINTER(c_ubyte))
 
+# callback for OPT_SYM_RESOLVER option
+KS_SYM_RESOLVER = CFUNCTYPE(c_bool, c_char_p, POINTER(c_uint64))
 
 # access to error code via @errno of KsError
 # this also includes the @stat_count returned by ks_asm
@@ -184,6 +185,21 @@ class Ks(object):
         self._syntax = style
 
 
+    @property
+    def sym_resolver(self):
+        return
+
+
+    @sym_resolver.setter
+    def sym_resolver(self, resolver):
+        callback = KS_SYM_RESOLVER(resolver)
+        status = _ks.ks_option(self._ksh, KS_OPT_SYM_RESOLVER, callback)
+        if status != KS_ERR_OK:
+            raise KsError(status)
+        # save resolver
+        self._sym_resolver = callback
+
+
     # assemble a string of assembly
     def asm(self, string, addr = 0):
         encode = POINTER(c_ubyte)()
diff --git a/bindings/python/keystone/keystone_const.py b/bindings/python/keystone/keystone_const.py
index d81803717966d572bb66443abc80c6a7a50e92d9..5ea12fbb1276e1da27c723643e1c6e8c082f5115 100644
--- a/bindings/python/keystone/keystone_const.py
+++ b/bindings/python/keystone/keystone_const.py
@@ -78,6 +78,7 @@ KS_ERR_ASM_INVALIDOPERAND = 512
 KS_ERR_ASM_MISSINGFEATURE = 513
 KS_ERR_ASM_MNEMONICFAIL = 514
 KS_OPT_SYNTAX = 1
+KS_OPT_SYM_RESOLVER = 2
 KS_OPT_SYNTAX_INTEL = 1
 KS_OPT_SYNTAX_ATT = 2
 KS_OPT_SYNTAX_NASM = 4
diff --git a/bindings/python/sample.py b/bindings/python/sample.py
index db634147242402373f26c99399355c74e9369412..2e2830eecb771fc565da6a94021887f9e45b8491 100755
--- a/bindings/python/sample.py
+++ b/bindings/python/sample.py
@@ -20,6 +20,33 @@ def test_ks(arch, mode, code, syntax=0):
     print("]")
 
 
+# test symbol resolver
+def test_sym_resolver():
+    def sym_resolver(symbol, value):
+        # is this the missing symbol we want to handle?
+        if symbol == "_l1":
+            # put value of this symbol in @value
+            value = 0x1002
+            # we handled this symbol, so return true
+            return True
+
+        # we did not handle this symbol, so return false
+        return False
+
+    ks = Ks(KS_ARCH_X86, KS_MODE_32)
+
+    # register callback for symbol resolver
+    ks.sym_resolver = sym_resolver
+
+    CODE = b"jmp _l1; nop; _l1:"
+    encoding, count = ks.asm(CODE, 0x1000)
+
+    print("%s = [ " % CODE, end='')
+    for i in encoding:
+        print("%02x " % i, end='')
+    print("]")
+
+
 if __name__ == '__main__':
     # X86
     test_ks(KS_ARCH_X86, KS_MODE_16, b"add eax, ecx")
@@ -66,3 +93,6 @@ if __name__ == '__main__':
 
     # SystemZ
     test_ks(KS_ARCH_SYSTEMZ, KS_MODE_BIG_ENDIAN, b"a %r0, 4095(%r15,%r1)")
+
+    # test symbol resolver
+    test_sym_resolver()
diff --git a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
index fa427c2faa19a8386808f2cb5f79e78c06b0e2a1..5d3ff81f239211e36b7b8310c847bdfdc20bb2ec 100644
--- a/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
+++ b/bindings/ruby/keystone_gem/lib/keystone/keystone_const.rb
@@ -80,6 +80,7 @@ module Keystone
 	KS_ERR_ASM_MISSINGFEATURE = 513
 	KS_ERR_ASM_MNEMONICFAIL = 514
 	KS_OPT_SYNTAX = 1
+	KS_OPT_SYM_RESOLVER = 2
 	KS_OPT_SYNTAX_INTEL = 1
 	KS_OPT_SYNTAX_ATT = 2
 	KS_OPT_SYNTAX_NASM = 4
diff --git a/bindings/rust/src/keystone_const.rs b/bindings/rust/src/keystone_const.rs
index 583579771a710505fc63425d93eb4a72613b42c2..436e875477e4a844629dda9584f039608fa5fb74 100644
--- a/bindings/rust/src/keystone_const.rs
+++ b/bindings/rust/src/keystone_const.rs
@@ -88,6 +88,7 @@ impl OptionType {
 
 bitflags! {
 	pub flags OptionValue : libc::size_t {
+		const OPT_SYM_RESOLVER = 2,
 		const OPT_SYNTAX_INTEL = 1,
 		const OPT_SYNTAX_ATT = 2,
 		const OPT_SYNTAX_NASM = 4,