Refactor the syscall table into a shared location

The ftrace trace processor had this mapping in order to convert the
syscall ids found in ftrace logs to proper names. A new feature is being
added that allows filtering syscalls during tracing. It will need to
convert string names into numbers within traced_probes.

Test: ran perfetto_unittest
Change-Id: I6198c3f33112d41db792f7e52641d9309a68aa7c
diff --git a/Android.bp b/Android.bp
index b41580b..81a3247 100644
--- a/Android.bp
+++ b/Android.bp
@@ -554,6 +554,7 @@
         ":perfetto_src_ipc_common",
         ":perfetto_src_ipc_host",
         ":perfetto_src_kallsyms_kallsyms",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_protozero_filtering_bytecode_common",
         ":perfetto_src_protozero_filtering_bytecode_parser",
         ":perfetto_src_protozero_filtering_message_filter",
@@ -1165,6 +1166,7 @@
         ":perfetto_src_ipc_host",
         ":perfetto_src_ipc_perfetto_ipc",
         ":perfetto_src_kallsyms_kallsyms",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_protozero_filtering_bytecode_common",
         ":perfetto_src_protozero_filtering_bytecode_generator",
         ":perfetto_src_protozero_filtering_bytecode_parser",
@@ -1454,6 +1456,7 @@
         ":perfetto_src_ipc_host",
         ":perfetto_src_ipc_perfetto_ipc",
         ":perfetto_src_kallsyms_kallsyms",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_protozero_filtering_bytecode_common",
         ":perfetto_src_protozero_filtering_bytecode_parser",
         ":perfetto_src_protozero_filtering_message_filter",
@@ -1928,6 +1931,7 @@
         ":perfetto_src_ipc_host",
         ":perfetto_src_ipc_perfetto_ipc",
         ":perfetto_src_kallsyms_kallsyms",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_profiling_common_callstack_trie",
         ":perfetto_src_profiling_common_interner",
         ":perfetto_src_profiling_common_interning_output",
@@ -8106,6 +8110,14 @@
     ],
 }
 
+// GN: //src/kernel_utils:syscall_table
+filegroup {
+    name: "perfetto_src_kernel_utils_syscall_table",
+    srcs: [
+        "src/kernel_utils/syscall_table.cc",
+    ],
+}
+
 // GN: //src/perfetto_cmd:gen_cc_config_descriptor
 genrule {
     name: "perfetto_src_perfetto_cmd_gen_cc_config_descriptor",
@@ -10773,6 +10785,7 @@
         ":perfetto_src_ipc_unittests",
         ":perfetto_src_kallsyms_kallsyms",
         ":perfetto_src_kallsyms_unittests",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_perfetto_cmd_perfetto_cmd",
         ":perfetto_src_perfetto_cmd_protos_cpp_gen",
         ":perfetto_src_perfetto_cmd_trigger_producer",
@@ -11156,6 +11169,7 @@
         ":perfetto_src_base_http_http",
         ":perfetto_src_base_unix_socket",
         ":perfetto_src_base_version",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_profiling_deobfuscator",
         ":perfetto_src_profiling_symbolizer_symbolize_database",
         ":perfetto_src_profiling_symbolizer_symbolizer",
@@ -11334,6 +11348,7 @@
         ":perfetto_protos_third_party_pprof_zero_gen",
         ":perfetto_src_base_base",
         ":perfetto_src_base_version",
+        ":perfetto_src_kernel_utils_syscall_table",
         ":perfetto_src_profiling_deobfuscator",
         ":perfetto_src_profiling_symbolizer_symbolize_database",
         ":perfetto_src_profiling_symbolizer_symbolizer",
diff --git a/BUILD b/BUILD
index 04b296e..e1f40f8 100644
--- a/BUILD
+++ b/BUILD
@@ -230,6 +230,7 @@
         ":src_android_stats_android_stats",
         ":src_android_stats_perfetto_atoms",
         ":src_kallsyms_kallsyms",
+        ":src_kernel_utils_syscall_table",
         ":src_protozero_filtering_bytecode_common",
         ":src_protozero_filtering_bytecode_parser",
         ":src_protozero_filtering_message_filter",
@@ -850,6 +851,20 @@
     ],
 )
 
+# GN target: //src/kernel_utils:syscall_table
+perfetto_filegroup(
+    name = "src_kernel_utils_syscall_table",
+    srcs = [
+        "src/kernel_utils/syscall_table.cc",
+        "src/kernel_utils/syscall_table.h",
+        "src/kernel_utils/syscalls_aarch32.h",
+        "src/kernel_utils/syscalls_aarch64.h",
+        "src/kernel_utils/syscalls_armeabi.h",
+        "src/kernel_utils/syscalls_x86.h",
+        "src/kernel_utils/syscalls_x86_64.h",
+    ],
+)
+
 perfetto_cc_proto_descriptor(
     name = "src_perfetto_cmd_gen_cc_config_descriptor",
     deps = [
@@ -1674,11 +1689,6 @@
         "src/trace_processor/importers/proto/vulkan_memory_tracker.cc",
         "src/trace_processor/importers/proto/vulkan_memory_tracker.h",
         "src/trace_processor/importers/syscalls/syscall_tracker.cc",
-        "src/trace_processor/importers/syscalls/syscalls_aarch32.h",
-        "src/trace_processor/importers/syscalls/syscalls_aarch64.h",
-        "src/trace_processor/importers/syscalls/syscalls_armeabi.h",
-        "src/trace_processor/importers/syscalls/syscalls_x86.h",
-        "src/trace_processor/importers/syscalls/syscalls_x86_64.h",
         "src/trace_processor/importers/systrace/systrace_line_parser.cc",
         "src/trace_processor/importers/systrace/systrace_line_parser.h",
         "src/trace_processor/importers/systrace/systrace_line_tokenizer.cc",
@@ -4106,6 +4116,7 @@
 perfetto_cc_library(
     name = "trace_processor",
     srcs = [
+        ":src_kernel_utils_syscall_table",
         ":src_trace_processor_analysis_analysis",
         ":src_trace_processor_db_db",
         ":src_trace_processor_dynamic_dynamic",
@@ -4219,6 +4230,7 @@
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_storage",
         ":include_perfetto_trace_processor_trace_processor",
+        ":src_kernel_utils_syscall_table",
         ":src_profiling_deobfuscator",
         ":src_profiling_symbolizer_symbolize_database",
         ":src_profiling_symbolizer_symbolizer",
@@ -4397,6 +4409,7 @@
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_storage",
         ":include_perfetto_trace_processor_trace_processor",
+        ":src_kernel_utils_syscall_table",
         ":src_profiling_deobfuscator",
         ":src_profiling_symbolizer_symbolize_database",
         ":src_profiling_symbolizer_symbolizer",
diff --git a/src/kernel_utils/BUILD.gn b/src/kernel_utils/BUILD.gn
new file mode 100644
index 0000000..5470a76
--- /dev/null
+++ b/src/kernel_utils/BUILD.gn
@@ -0,0 +1,29 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source_set("syscall_table") {
+  deps = [
+    "../../gn:default_deps",
+    "../base",
+  ]
+  sources = [
+    "syscall_table.h",
+    "syscall_table.cc",
+    "syscalls_aarch32.h",
+    "syscalls_aarch64.h",
+    "syscalls_armeabi.h",
+    "syscalls_x86.h",
+    "syscalls_x86_64.h",
+  ]
+}
diff --git a/src/kernel_utils/syscall_table.cc b/src/kernel_utils/syscall_table.cc
new file mode 100644
index 0000000..5d7ad00
--- /dev/null
+++ b/src/kernel_utils/syscall_table.cc
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "src/kernel_utils/syscall_table.h"
+
+#include <sys/utsname.h>
+
+#include "src/kernel_utils/syscalls_aarch32.h"
+#include "src/kernel_utils/syscalls_aarch64.h"
+#include "src/kernel_utils/syscalls_armeabi.h"
+#include "src/kernel_utils/syscalls_x86.h"
+#include "src/kernel_utils/syscalls_x86_64.h"
+
+namespace perfetto {
+
+template <typename T>
+constexpr size_t GetSyscalls(const T&) {
+  static_assert(std::extent<T>::value <= kMaxSyscalls,
+                "kMaxSyscalls too small");
+  return std::extent<T>::value;
+}
+
+SyscallTable::SyscallTable(Architecture arch) {
+  static const char* kSyscalls_Unknown[] = {nullptr};
+
+  switch (arch) {
+    case kArmEabi:
+      syscall_count_ = GetSyscalls(kSyscalls_ArmEabi);
+      syscall_table_ = &kSyscalls_ArmEabi[0];
+      break;
+    case kAarch32:
+      syscall_count_ = GetSyscalls(kSyscalls_Aarch32);
+      syscall_table_ = &kSyscalls_Aarch32[0];
+      break;
+    case kAarch64:
+      syscall_count_ = GetSyscalls(kSyscalls_Aarch64);
+      syscall_table_ = &kSyscalls_Aarch64[0];
+      break;
+    case kX86_64:
+      syscall_count_ = GetSyscalls(kSyscalls_x86_64);
+      syscall_table_ = &kSyscalls_x86_64[0];
+      break;
+    case kX86:
+      syscall_count_ = GetSyscalls(kSyscalls_x86);
+      syscall_table_ = &kSyscalls_x86[0];
+      break;
+    case kUnknown:
+      syscall_count_ = 0;
+      syscall_table_ = &kSyscalls_Unknown[0];
+      break;
+  }
+}
+
+Architecture SyscallTable::ArchFromString(base::StringView machine) {
+  if (machine == "aarch64") {
+    return kAarch64;
+  } else if (machine == "armv8l") {
+    return kArmEabi;
+  } else if (machine == "armv7l") {
+    return kAarch32;
+  } else if (machine == "x86_64") {
+    return kX86_64;
+  } else if (machine == "i686") {
+    return kX86;
+  } else {
+    return kUnknown;
+  }
+}
+
+SyscallTable SyscallTable::FromCurrentArch() {
+  struct utsname uname_info;
+  Architecture arch = kUnknown;
+  if (uname(&uname_info) == 0) {
+    arch = ArchFromString(uname_info.machine);
+  }
+
+  return SyscallTable(arch);
+}
+
+base::Optional<size_t> SyscallTable::GetByName(const std::string& name) const {
+  for (size_t i = 0; i < syscall_count_; i++) {
+    if (name == syscall_table_[i]) {
+      return i;
+    }
+  }
+  return base::nullopt;
+}
+
+const char* SyscallTable::GetById(size_t id) const {
+  if (id < syscall_count_) {
+    return syscall_table_[id];
+  }
+  return nullptr;
+}
+
+}  // namespace perfetto
diff --git a/src/kernel_utils/syscall_table.h b/src/kernel_utils/syscall_table.h
new file mode 100644
index 0000000..ddcc080
--- /dev/null
+++ b/src/kernel_utils/syscall_table.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_KERNEL_UTILS_SYSCALL_TABLE_H_
+#define SRC_KERNEL_UTILS_SYSCALL_TABLE_H_
+
+#include <memory>
+#include <string>
+
+#include "perfetto/ext/base/optional.h"
+#include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+
+static constexpr size_t kMaxSyscalls = 550;
+
+enum Architecture {
+  kUnknown = 0,
+  kArmEabi,  // 32-bit kernel running a 32-bit process (most old devices).
+  kAarch32,  // 64-bit kernel running a 32-bit process (should be rare).
+  kAarch64,  // 64-bit kernel running a 64-bit process (most new devices).
+  kX86_64,
+  kX86,
+};
+
+class SyscallTable {
+ public:
+  SyscallTable(Architecture arch);
+
+  // Return the architecture enum for the given uname machine string.
+  static Architecture ArchFromString(base::StringView machine);
+
+  // Returns the syscall table based on the current machine's architecture.
+  static SyscallTable FromCurrentArch();
+
+  // Returns the syscall id for the syscall with the given name. If the syscall
+  // is not found, returns nullopt.
+  base::Optional<size_t> GetByName(const std::string& name) const;
+
+  // Returns the syscall name for the syscall with the given id. If the syscall
+  // is not found, returns nullptr.
+  const char* GetById(size_t id) const;
+
+ private:
+  size_t syscall_count_;
+  const char* const* syscall_table_;
+};
+}  // namespace perfetto
+
+#endif  // SRC_KERNEL_UTILS_SYSCALL_TABLE_H_
diff --git a/src/trace_processor/importers/syscalls/syscalls_aarch32.h b/src/kernel_utils/syscalls_aarch32.h
similarity index 98%
rename from src/trace_processor/importers/syscalls/syscalls_aarch32.h
rename to src/kernel_utils/syscalls_aarch32.h
index e6a5475..e1bb6b3 100644
--- a/src/trace_processor/importers/syscalls/syscalls_aarch32.h
+++ b/src/kernel_utils/syscalls_aarch32.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH32_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH32_H_
+#ifndef SRC_KERNEL_UTILS_SYSCALLS_AARCH32_H_
+#define SRC_KERNEL_UTILS_SYSCALLS_AARCH32_H_
 
 namespace perfetto {
-namespace trace_processor {
 
 // See tools/extract_linux_syscall_tables .
 constexpr const char* kSyscalls_Aarch32[] = {
@@ -423,7 +422,6 @@
     "sys_rseq",                    // 398
 };
 
-}  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH32_H_
+#endif  // SRC_KERNEL_UTILS_SYSCALLS_AARCH32_H_
diff --git a/src/trace_processor/importers/syscalls/syscalls_aarch64.h b/src/kernel_utils/syscalls_aarch64.h
similarity index 97%
rename from src/trace_processor/importers/syscalls/syscalls_aarch64.h
rename to src/kernel_utils/syscalls_aarch64.h
index 67a82b6..8a95e89 100644
--- a/src/trace_processor/importers/syscalls/syscalls_aarch64.h
+++ b/src/kernel_utils/syscalls_aarch64.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH64_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH64_H_
+#ifndef SRC_KERNEL_UTILS_SYSCALLS_AARCH64_H_
+#define SRC_KERNEL_UTILS_SYSCALLS_AARCH64_H_
 
 namespace perfetto {
-namespace trace_processor {
 
 // See tools/extract_linux_syscall_tables .
 constexpr const char* kSyscalls_Aarch64[] = {
@@ -318,7 +317,6 @@
     "sys_rseq",                    // 293
 };
 
-}  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_AARCH64_H_
+#endif  // SRC_KERNEL_UTILS_SYSCALLS_AARCH64_H_
diff --git a/src/trace_processor/importers/syscalls/syscalls_armeabi.h b/src/kernel_utils/syscalls_armeabi.h
similarity index 98%
rename from src/trace_processor/importers/syscalls/syscalls_armeabi.h
rename to src/kernel_utils/syscalls_armeabi.h
index eed478e..22b3e8c 100644
--- a/src/trace_processor/importers/syscalls/syscalls_armeabi.h
+++ b/src/kernel_utils/syscalls_armeabi.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_ARMEABI_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_ARMEABI_H_
+#ifndef SRC_KERNEL_UTILS_SYSCALLS_ARMEABI_H_
+#define SRC_KERNEL_UTILS_SYSCALLS_ARMEABI_H_
 
 namespace perfetto {
-namespace trace_processor {
 
 // See tools/extract_linux_syscall_tables .
 constexpr const char* kSyscalls_ArmEabi[] = {
@@ -424,7 +423,6 @@
     "sys_io_pgetevents",           // 399
 };
 
-}  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_ARMEABI_H_
+#endif  // SRC_KERNEL_UTILS_SYSCALLS_ARMEABI_H_
diff --git a/src/trace_processor/importers/syscalls/syscalls_x86.h b/src/kernel_utils/syscalls_x86.h
similarity index 98%
rename from src/trace_processor/importers/syscalls/syscalls_x86.h
rename to src/kernel_utils/syscalls_x86.h
index ddd136c..b89a5da 100644
--- a/src/trace_processor/importers/syscalls/syscalls_x86.h
+++ b/src/kernel_utils/syscalls_x86.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_H_
+#ifndef SRC_KERNEL_UTILS_SYSCALLS_X86_H_
+#define SRC_KERNEL_UTILS_SYSCALLS_X86_H_
 
 namespace perfetto {
-namespace trace_processor {
 
 // See tools/extract_linux_syscall_tables .
 constexpr const char* kSyscalls_x86[] = {
@@ -411,7 +410,6 @@
     "sys_rseq",                    // 386
 };
 
-}  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_H_
+#endif  // SRC_KERNEL_UTILS_SYSCALLS_X86_H_
diff --git a/src/trace_processor/importers/syscalls/syscalls_x86_64.h b/src/kernel_utils/syscalls_x86_64.h
similarity index 98%
rename from src/trace_processor/importers/syscalls/syscalls_x86_64.h
rename to src/kernel_utils/syscalls_x86_64.h
index 01c1b8c..19fd5dc 100644
--- a/src/trace_processor/importers/syscalls/syscalls_x86_64.h
+++ b/src/kernel_utils/syscalls_x86_64.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_64_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_64_H_
+#ifndef SRC_KERNEL_UTILS_SYSCALLS_X86_64_H_
+#define SRC_KERNEL_UTILS_SYSCALLS_X86_64_H_
 
 namespace perfetto {
-namespace trace_processor {
 
 // See tools/extract_linux_syscall_tables .
 constexpr const char* kSyscalls_x86_64[] = {
@@ -572,7 +571,6 @@
     "sys_pwritev2",                // 547
 };
 
-}  // namespace trace_processor
 }  // namespace perfetto
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_SYSCALLS_SYSCALLS_X86_64_H_
+#endif  // SRC_KERNEL_UTILS_SYSCALLS_X86_64_H_
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 6e50468..600a8f5 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -206,6 +206,7 @@
     "../../protos/perfetto/trace/system_info:zero",
     "../../protos/perfetto/trace/track_event:zero",
     "../../protos/perfetto/trace/translation:zero",
+    "../../src/kernel_utils:syscall_table",
   ]
 
   # json_utils optionally depends on jsoncpp.
@@ -273,11 +274,6 @@
     "importers/proto/vulkan_memory_tracker.cc",
     "importers/proto/vulkan_memory_tracker.h",
     "importers/syscalls/syscall_tracker.cc",
-    "importers/syscalls/syscalls_aarch32.h",
-    "importers/syscalls/syscalls_aarch64.h",
-    "importers/syscalls/syscalls_armeabi.h",
-    "importers/syscalls/syscalls_x86.h",
-    "importers/syscalls/syscalls_x86_64.h",
     "importers/systrace/systrace_line_parser.cc",
     "importers/systrace/systrace_line_parser.h",
     "importers/systrace/systrace_line_tokenizer.cc",
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 526bb60..56469af 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -455,16 +455,9 @@
                                              utsname_blob.size);
     base::StringView machine = utsname.machine();
     SyscallTracker* syscall_tracker = SyscallTracker::GetOrCreate(context_);
-    if (machine == "aarch64") {
-      syscall_tracker->SetArchitecture(kAarch64);
-    } else if (machine == "armv8l") {
-      syscall_tracker->SetArchitecture(kArmEabi);
-    } else if (machine == "armv7l") {
-      syscall_tracker->SetArchitecture(kAarch32);
-    } else if (machine == "x86_64") {
-      syscall_tracker->SetArchitecture(kX86_64);
-    } else if (machine == "i686") {
-      syscall_tracker->SetArchitecture(kX86);
+    Architecture arch = SyscallTable::ArchFromString(machine);
+    if (arch != kUnknown) {
+      syscall_tracker->SetArchitecture(arch);
     } else {
       PERFETTO_ELOG("Unknown architecture %s. Syscall traces will not work.",
                     machine.ToStdString().c_str());
diff --git a/src/trace_processor/importers/syscalls/syscall_tracker.cc b/src/trace_processor/importers/syscalls/syscall_tracker.cc
index a60be09..f092455 100644
--- a/src/trace_processor/importers/syscalls/syscall_tracker.cc
+++ b/src/trace_processor/importers/syscalls/syscall_tracker.cc
@@ -20,26 +20,11 @@
 #include <type_traits>
 #include <utility>
 
+#include "src/kernel_utils/syscall_table.h"
 #include "src/trace_processor/storage/stats.h"
 
-#include "src/trace_processor/importers/syscalls/syscalls_aarch32.h"
-#include "src/trace_processor/importers/syscalls/syscalls_aarch64.h"
-#include "src/trace_processor/importers/syscalls/syscalls_armeabi.h"
-#include "src/trace_processor/importers/syscalls/syscalls_x86.h"
-#include "src/trace_processor/importers/syscalls/syscalls_x86_64.h"
-
 namespace perfetto {
 namespace trace_processor {
-namespace {
-
-template <typename T>
-constexpr size_t GetSyscalls(const T&) {
-  static_assert(std::extent<T>::value <= kMaxSyscalls,
-                "kMaxSyscalls too small");
-  return std::extent<T>::value;
-}
-
-}  // namespace
 
 // TODO(primiano): The current design is broken in case of 32-bit processes
 // running on 64-bit kernel. At least on ARM, the syscal numbers don't match
@@ -55,41 +40,12 @@
 SyscallTracker::~SyscallTracker() = default;
 
 void SyscallTracker::SetArchitecture(Architecture arch) {
-  const char* kSyscalls_Unknown[] = {nullptr};
-  size_t num_syscalls = 0;
-  const char* const* syscall_table = nullptr;
-
-  switch (arch) {
-    case kArmEabi:
-      num_syscalls = GetSyscalls(kSyscalls_ArmEabi);
-      syscall_table = &kSyscalls_ArmEabi[0];
-      break;
-    case kAarch32:
-      num_syscalls = GetSyscalls(kSyscalls_Aarch32);
-      syscall_table = &kSyscalls_Aarch32[0];
-      break;
-    case kAarch64:
-      num_syscalls = GetSyscalls(kSyscalls_Aarch64);
-      syscall_table = &kSyscalls_Aarch64[0];
-      break;
-    case kX86_64:
-      num_syscalls = GetSyscalls(kSyscalls_x86_64);
-      syscall_table = &kSyscalls_x86_64[0];
-      break;
-    case kX86:
-      num_syscalls = GetSyscalls(kSyscalls_x86);
-      syscall_table = &kSyscalls_x86[0];
-      break;
-    case kUnknown:
-      num_syscalls = 0;
-      syscall_table = &kSyscalls_Unknown[0];
-      break;
-  }
+  SyscallTable syscalls(arch);
 
   for (size_t i = 0; i < kMaxSyscalls; i++) {
     StringId id = kNullStringId;
-    if (i < num_syscalls && syscall_table[i] && *syscall_table[i]) {
-      const char* name = syscall_table[i];
+    const char* name = syscalls.GetById(i);
+    if (name && *name) {
       id = context_->storage->InternString(name);
       if (!strcmp(name, "sys_write"))
         sys_write_string_id_ = id;
diff --git a/src/trace_processor/importers/syscalls/syscall_tracker.h b/src/trace_processor/importers/syscalls/syscall_tracker.h
index 666a220..72bbd9d 100644
--- a/src/trace_processor/importers/syscalls/syscall_tracker.h
+++ b/src/trace_processor/importers/syscalls/syscall_tracker.h
@@ -21,6 +21,7 @@
 #include <tuple>
 
 #include "perfetto/ext/base/string_view.h"
+#include "src/kernel_utils/syscall_table.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/storage/trace_storage.h"
@@ -30,17 +31,6 @@
 namespace perfetto {
 namespace trace_processor {
 
-static constexpr size_t kMaxSyscalls = 550;
-
-enum Architecture {
-  kUnknown = 0,
-  kArmEabi,  // 32-bit kernel running a 32-bit process (most old devices).
-  kAarch32,  // 64-bit kernel running a 32-bit process (should be rare).
-  kAarch64,  // 64-bit kernel running a 64-bit process (most new devices).
-  kX86_64,
-  kX86,
-};
-
 class SyscallTracker : public Destructible {
  public:
   SyscallTracker(const SyscallTracker&) = delete;
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index 44ed22c..f56d2c5 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -54,6 +54,7 @@
     "../../../protos/perfetto/config/ftrace:cpp",
     "../../../protos/perfetto/trace:zero",
     "../../../protos/perfetto/trace/ps:zero",
+    "../../../src/kernel_utils:syscall_table",
     "../../android_stats",
     "../../base",
     "../../tracing/core",