From 986b7367f7b6454b1f9c4e9b9e705ee4130c1908 Mon Sep 17 00:00:00 2001
From: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Sun, 30 Oct 2016 23:26:10 +0800
Subject: [PATCH] arm: handle V8 mode

---
 kstool/kstool.cpp       | 20 ++++++++++++++++++++
 llvm/keystone/ks.cpp    | 36 ++++++++++++++++++++++++++++--------
 llvm/keystone/ks_priv.h |  2 +-
 3 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/kstool/kstool.cpp b/kstool/kstool.cpp
index 379b385..8038f1a 100644
--- a/kstool/kstool.cpp
+++ b/kstool/kstool.cpp
@@ -40,6 +40,10 @@ static void usage(char *prog)
         printf("        armbe:     ARM - big endian\n");
         printf("        thumb:     Thumb - little endian\n");
         printf("        thumbbe:   Thumb - big endian\n");
+        printf("        armv8:     ARM V8 - little endian\n");
+        printf("        armv8be:   ARM V8 - big endian\n");
+        printf("        thumbv8:   Thumb V8 - little endian\n");
+        printf("        thumbv8be: Thumb V8 - big endian\n");
     }
 
     if (ks_arch_supported(KS_ARCH_ARM64)) {
@@ -207,6 +211,22 @@ int main(int argc, char **argv)
         err = ks_open(KS_ARCH_ARM, KS_MODE_THUMB+KS_MODE_BIG_ENDIAN, &ks);
     }
 
+    if (!strcmp(mode, "armv8")) {
+        err = ks_open(KS_ARCH_ARM, KS_MODE_ARM+KS_MODE_LITTLE_ENDIAN+KS_MODE_V8, &ks);
+    }
+
+    if (!strcmp(mode, "armv8be")) {
+        err = ks_open(KS_ARCH_ARM, KS_MODE_ARM+KS_MODE_BIG_ENDIAN+KS_MODE_V8, &ks);
+    }
+
+    if (!strcmp(mode, "thumbv8")) {
+        err = ks_open(KS_ARCH_ARM, KS_MODE_THUMB+KS_MODE_LITTLE_ENDIAN+KS_MODE_V8, &ks);
+    }
+
+    if (!strcmp(mode, "thumbv8be")) {
+        err = ks_open(KS_ARCH_ARM, KS_MODE_THUMB+KS_MODE_BIG_ENDIAN+KS_MODE_V8, &ks);
+    }
+
     if (!strcmp(mode, "arm64")) {
         err = ks_open(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN, &ks);
     }
diff --git a/llvm/keystone/ks.cpp b/llvm/keystone/ks.cpp
index ea9758d..d1819f0 100644
--- a/llvm/keystone/ks.cpp
+++ b/llvm/keystone/ks.cpp
@@ -266,16 +266,36 @@ ks_err ks_open(ks_arch arch, int mode, ks_engine **result)
                     return KS_ERR_MODE;
                 }
 
-                if (mode & KS_MODE_THUMB) {
-                    if (mode & KS_MODE_BIG_ENDIAN)
-                        TripleName = "thumbebv7";
-                    else
-                        TripleName = "thumbv7";
-                } else {
-                    if (mode & KS_MODE_BIG_ENDIAN)
+                switch(mode) {
+                    default:
+                        return KS_ERR_MODE;
+                    // big-endian
+                    case KS_MODE_BIG_ENDIAN | KS_MODE_V8 | KS_MODE_ARM:
+                        TripleName = "armv8eb";
+                        break;
+                    case KS_MODE_BIG_ENDIAN | KS_MODE_V8 | KS_MODE_THUMB:
+                        TripleName = "thumbv8eb";
+                        break;
+                    case KS_MODE_BIG_ENDIAN | KS_MODE_ARM:
                         TripleName = "armv7eb";
-                    else
+                        break;
+                    case KS_MODE_BIG_ENDIAN | KS_MODE_THUMB:
+                        TripleName = "thumbebv7";
+                        break;
+
+                    // little-endian
+                    case KS_MODE_LITTLE_ENDIAN | KS_MODE_V8 | KS_MODE_ARM:
+                        TripleName = "armv8";
+                        break;
+                    case KS_MODE_LITTLE_ENDIAN | KS_MODE_V8 | KS_MODE_THUMB:
+                        TripleName = "thumbv8";
+                        break;
+                    case KS_MODE_LITTLE_ENDIAN | KS_MODE_ARM:
                         TripleName = "armv7";
+                        break;
+                    case KS_MODE_LITTLE_ENDIAN | KS_MODE_THUMB:
+                        TripleName = "thumbv7";
+                        break;
                 }
 
                 InitKs(arch, ks, TripleName);
diff --git a/llvm/keystone/ks_priv.h b/llvm/keystone/ks_priv.h
index 4fafd0e..311bb07 100644
--- a/llvm/keystone/ks_priv.h
+++ b/llvm/keystone/ks_priv.h
@@ -20,7 +20,7 @@
 
 // These are masks of supported modes for each cpu/arch.
 // They should be updated when changes are made to the ks_mode enum typedef.
-#define KS_MODE_ARM_MASK    (KS_MODE_ARM|KS_MODE_THUMB|KS_MODE_LITTLE_ENDIAN|KS_MODE_BIG_ENDIAN)
+#define KS_MODE_ARM_MASK    (KS_MODE_ARM|KS_MODE_THUMB|KS_MODE_LITTLE_ENDIAN|KS_MODE_BIG_ENDIAN|KS_MODE_V8)
 #define KS_MODE_MIPS_MASK   (KS_MODE_MIPS32|KS_MODE_MIPS64|KS_MODE_LITTLE_ENDIAN|KS_MODE_BIG_ENDIAN)
 #define KS_MODE_X86_MASK    (KS_MODE_16|KS_MODE_32|KS_MODE_64|KS_MODE_LITTLE_ENDIAN)
 #define KS_MODE_PPC_MASK    (KS_MODE_PPC32|KS_MODE_PPC64|KS_MODE_LITTLE_ENDIAN|KS_MODE_BIG_ENDIAN)
-- 
GitLab