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)29SyscallTable::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)49Architecture 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()64SyscallTable 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) const78std::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) const87const 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