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