| // Copyright 2020 The Crashpad Authors. All rights reserved. |
| // |
| // 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 "snapshot/ios/system_snapshot_ios.h" |
| |
| #include <mach/mach.h> |
| #include <stddef.h> |
| #include <sys/sysctl.h> |
| #include <sys/types.h> |
| #include <sys/utsname.h> |
| |
| #include <algorithm> |
| |
| #include "base/logging.h" |
| #include "base/mac/mach_logging.h" |
| #include "base/strings/stringprintf.h" |
| #include "build/build_config.h" |
| #include "snapshot/cpu_context.h" |
| #include "snapshot/posix/timezone.h" |
| #include "util/mac/mac_util.h" |
| #include "util/numeric/in_range_cast.h" |
| |
| namespace crashpad { |
| |
| namespace internal { |
| |
| SystemSnapshotIOS::SystemSnapshotIOS() |
| : SystemSnapshot(), |
| os_version_build_(), |
| machine_description_(), |
| os_version_major_(0), |
| os_version_minor_(0), |
| os_version_bugfix_(0), |
| active_(0), |
| inactive_(0), |
| wired_(0), |
| free_(0), |
| cpu_count_(0), |
| cpu_vendor_(), |
| dst_status_(), |
| standard_offset_seconds_(0), |
| daylight_offset_seconds_(0), |
| standard_name_(), |
| daylight_name_(), |
| initialized_() {} |
| |
| SystemSnapshotIOS::~SystemSnapshotIOS() {} |
| |
| void SystemSnapshotIOS::Initialize(const IOSSystemDataCollector& system_data) { |
| INITIALIZATION_STATE_SET_INITIALIZING(initialized_); |
| |
| system_data.OSVersion(&os_version_major_, |
| &os_version_minor_, |
| &os_version_bugfix_, |
| &os_version_build_); |
| machine_description_ = system_data.MachineDescription(); |
| cpu_count_ = system_data.ProcessorCount(); |
| cpu_vendor_ = system_data.CPUVendor(); |
| if (system_data.HasDaylightSavingTime()) { |
| dst_status_ = system_data.IsDaylightSavingTime() |
| ? SystemSnapshot::kObservingDaylightSavingTime |
| : SystemSnapshot::kObservingStandardTime; |
| } else { |
| dst_status_ = SystemSnapshot::kDoesNotObserveDaylightSavingTime; |
| } |
| standard_offset_seconds_ = system_data.StandardOffsetSeconds(); |
| daylight_offset_seconds_ = system_data.DaylightOffsetSeconds(); |
| standard_name_ = system_data.StandardName(); |
| daylight_name_ = system_data.DaylightName(); |
| |
| // Currently unused by minidump. |
| vm_size_t page_size; |
| host_page_size(mach_host_self(), &page_size); |
| mach_msg_type_number_t host_size = |
| sizeof(vm_statistics_data_t) / sizeof(integer_t); |
| vm_statistics_data_t vm_stat; |
| kern_return_t kr = host_statistics(mach_host_self(), |
| HOST_VM_INFO, |
| reinterpret_cast<host_info_t>(&vm_stat), |
| &host_size); |
| if (kr != KERN_SUCCESS) { |
| MACH_LOG(WARNING, kr) << "host_statistics"; |
| } |
| active_ = vm_stat.active_count * page_size; |
| inactive_ = vm_stat.inactive_count * page_size; |
| wired_ = vm_stat.wire_count * page_size; |
| free_ = vm_stat.free_count * page_size; |
| |
| INITIALIZATION_STATE_SET_VALID(initialized_); |
| } |
| |
| CPUArchitecture SystemSnapshotIOS::GetCPUArchitecture() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| #if defined(ARCH_CPU_X86_64) |
| return kCPUArchitectureX86_64; |
| #elif defined(ARCH_CPU_ARM64) |
| return kCPUArchitectureARM64; |
| #endif |
| } |
| |
| uint32_t SystemSnapshotIOS::CPURevision() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): sysctlbyname machdep.cpu.* returns -1 on iOS/ARM64, but |
| // consider recording this for X86_64 only. |
| return 0; |
| } |
| |
| uint8_t SystemSnapshotIOS::CPUCount() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return cpu_count_; |
| } |
| |
| std::string SystemSnapshotIOS::CPUVendor() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return cpu_vendor_; |
| } |
| |
| void SystemSnapshotIOS::CPUFrequency(uint64_t* current_hz, |
| uint64_t* max_hz) const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): sysctlbyname hw.cpufrequency returns -1 on iOS/ARM64, |
| // but consider recording this for X86_64 only. |
| *current_hz = 0; |
| *max_hz = 0; |
| } |
| |
| uint32_t SystemSnapshotIOS::CPUX86Signature() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider recording this for X86_64 only. |
| return 0; |
| } |
| |
| uint64_t SystemSnapshotIOS::CPUX86Features() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider recording this for X86_64 only. |
| return 0; |
| } |
| |
| uint64_t SystemSnapshotIOS::CPUX86ExtendedFeatures() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider recording this for X86_64 only. |
| return 0; |
| } |
| |
| uint32_t SystemSnapshotIOS::CPUX86Leaf7Features() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider recording this for X86_64 only. |
| return 0; |
| } |
| |
| bool SystemSnapshotIOS::CPUX86SupportsDAZ() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider recording this for X86_64 only. |
| return false; |
| } |
| |
| SystemSnapshot::OperatingSystem SystemSnapshotIOS::GetOperatingSystem() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return kOperatingSystemIOS; |
| } |
| |
| bool SystemSnapshotIOS::OSServer() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return false; |
| } |
| |
| void SystemSnapshotIOS::OSVersion(int* major, |
| int* minor, |
| int* bugfix, |
| std::string* build) const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| *major = os_version_major_; |
| *minor = os_version_minor_; |
| *bugfix = os_version_bugfix_; |
| build->assign(os_version_build_); |
| } |
| |
| std::string SystemSnapshotIOS::OSVersionFull() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return base::StringPrintf("%d.%d.%d %s", |
| os_version_major_, |
| os_version_minor_, |
| os_version_bugfix_, |
| os_version_build_.c_str()); |
| } |
| |
| std::string SystemSnapshotIOS::MachineDescription() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| return machine_description_; |
| } |
| |
| bool SystemSnapshotIOS::NXEnabled() const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| // TODO(justincohen): Consider using kern.nx when available (pre-iOS 13, |
| // pre-OS X 10.15). Otherwise the bit is always enabled. |
| return true; |
| } |
| |
| void SystemSnapshotIOS::TimeZone(DaylightSavingTimeStatus* dst_status, |
| int* standard_offset_seconds, |
| int* daylight_offset_seconds, |
| std::string* standard_name, |
| std::string* daylight_name) const { |
| INITIALIZATION_STATE_DCHECK_VALID(initialized_); |
| *dst_status = dst_status_; |
| *standard_offset_seconds = standard_offset_seconds_; |
| *daylight_offset_seconds = daylight_offset_seconds_; |
| standard_name->assign(standard_name_); |
| daylight_name->assign(daylight_name_); |
| } |
| |
| } // namespace internal |
| } // namespace crashpad |