xref: /aosp_15_r20/external/perfetto/src/kernel_utils/syscall_table.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "src/kernel_utils/syscall_table.h"
17 
18 #include "perfetto/base/build_config.h"
19 
20 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
21     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
22 #include <sys/utsname.h>
23 #endif
24 
25 #include "src/kernel_utils/syscall_table_generated.h"
26 
27 namespace perfetto {
28 
SyscallTable(Architecture arch)29 SyscallTable::SyscallTable(Architecture arch) {
30   switch (arch) {
31     case Architecture::kArm64:
32       *this = SyscallTable::Load<SyscallTable_arm64>();
33       break;
34     case Architecture::kArm32:
35       *this = SyscallTable::Load<SyscallTable_arm32>();
36       break;
37     case Architecture::kX86_64:
38       *this = SyscallTable::Load<SyscallTable_x86_64>();
39       break;
40     case Architecture::kX86:
41       *this = SyscallTable::Load<SyscallTable_x86>();
42       break;
43     case Architecture::kUnknown:
44       // The default field initializers take care of the null initialization.
45       break;
46   }
47 }
48 
ArchFromString(base::StringView machine)49 Architecture SyscallTable::ArchFromString(base::StringView machine) {
50   if (machine == "aarch64") {
51     return Architecture::kArm64;
52   } else if (machine == "armv8l" || machine == "armv7l") {
53     // armv8l is a 32 bit userspace process on a 64 bit kernel
54     return Architecture::kArm32;
55   } else if (machine == "x86_64") {
56     return Architecture::kX86_64;
57   } else if (machine == "i686") {
58     return Architecture::kX86;
59   } else {
60     return Architecture::kUnknown;
61   }
62 }
63 
FromCurrentArch()64 SyscallTable SyscallTable::FromCurrentArch() {
65   Architecture arch = Architecture::kUnknown;
66 
67 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
68     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
69   struct utsname uname_info;
70   if (uname(&uname_info) == 0) {
71     arch = ArchFromString(uname_info.machine);
72   }
73 #endif
74 
75   return SyscallTable(arch);
76 }
77 
GetByName(const std::string & name) const78 std::optional<size_t> SyscallTable::GetByName(const std::string& name) const {
79   for (size_t i = 0; i < syscall_count_; i++) {
80     if (name == &syscall_names_[syscall_offsets_[i]]) {
81       return i;
82     }
83   }
84   return std::nullopt;
85 }
86 
GetById(size_t id) const87 const char* SyscallTable::GetById(size_t id) const {
88   if (id < syscall_count_) {
89     return &syscall_names_[syscall_offsets_[id]];
90   }
91   return nullptr;
92 }
93 
94 }  // namespace perfetto
95