// Copyright 2018 The Crashpad Authors // // 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/fuchsia/system_snapshot_fuchsia.h" #include #include "base/check_op.h" #include "base/fuchsia/fuchsia_logging.h" #include "base/notreached.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "snapshot/posix/timezone.h" namespace crashpad { namespace internal { SystemSnapshotFuchsia::SystemSnapshotFuchsia() = default; SystemSnapshotFuchsia::~SystemSnapshotFuchsia() = default; void SystemSnapshotFuchsia::Initialize(const timeval* snapshot_time) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); snapshot_time_ = snapshot_time; // This version string mirrors `uname -a` as written by // garnet/bin/uname/uname.c, however, this information isn't provided by // uname(). Additionally, uname() seems to hang if the network is in a bad // state when attempting to retrieve the nodename, so avoid it for now. std::string kernel_version = zx_system_get_version_string(); #if defined(ARCH_CPU_X86_64) static constexpr const char kArch[] = "x86_64"; #elif defined(ARCH_CPU_ARM64) static constexpr const char kArch[] = "aarch64"; #else static constexpr const char kArch[] = "unknown"; #endif os_version_full_ = base::StringPrintf( "Zircon prerelease %s %s", kernel_version.c_str(), kArch); INITIALIZATION_STATE_SET_VALID(initialized_); } CPUArchitecture SystemSnapshotFuchsia::GetCPUArchitecture() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return kCPUArchitectureX86_64; #elif defined(ARCH_CPU_ARM64) return kCPUArchitectureARM64; #else #error Port #endif } uint32_t SystemSnapshotFuchsia::CPURevision() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.Revision(); #else // TODO(fuchsia/DX-712): Read actual revision. return 0; #endif } uint8_t SystemSnapshotFuchsia::CPUCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return base::saturated_cast(zx_system_get_num_cpus()); } std::string SystemSnapshotFuchsia::CPUVendor() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.Vendor(); #else // TODO(fuchsia/DX-712): Read actual vendor. return std::string(); #endif } void SystemSnapshotFuchsia::CPUFrequency(uint64_t* current_hz, uint64_t* max_hz) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); // TODO(scottmg): https://crashpad.chromium.org/bug/196. *current_hz = 0; *max_hz = 0; } uint32_t SystemSnapshotFuchsia::CPUX86Signature() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.Signature(); #else NOTREACHED(); return 0; #endif } uint64_t SystemSnapshotFuchsia::CPUX86Features() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.Features(); #else NOTREACHED(); return 0; #endif } uint64_t SystemSnapshotFuchsia::CPUX86ExtendedFeatures() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.ExtendedFeatures(); #else NOTREACHED(); return 0; #endif } uint32_t SystemSnapshotFuchsia::CPUX86Leaf7Features() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Leaf7Features(); #else NOTREACHED(); return 0; #endif } bool SystemSnapshotFuchsia::CPUX86SupportsDAZ() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.SupportsDAZ(); #else NOTREACHED(); return false; #endif } SystemSnapshot::OperatingSystem SystemSnapshotFuchsia::GetOperatingSystem() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return kOperatingSystemFuchsia; } bool SystemSnapshotFuchsia::OSServer() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return false; } void SystemSnapshotFuchsia::OSVersion(int* major, int* minor, int* bugfix, std::string* build) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); // TODO(scottmg): https://crashpad.chromium.org/bug/196. There's no version // available to be reported yet. *major = 0; *minor = 0; *bugfix = 0; *build = std::string(); } std::string SystemSnapshotFuchsia::OSVersionFull() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return os_version_full_; } std::string SystemSnapshotFuchsia::MachineDescription() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); // TODO(scottmg): https://crashpad.chromium.org/bug/196. Not yet available, // upstream ZX-1775. return std::string(); } bool SystemSnapshotFuchsia::NXEnabled() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); #if defined(ARCH_CPU_X86_64) return cpuid_.NXEnabled(); #else // TODO(fuchsia/DX-712): Read actual NX bit value. return false; #endif } void SystemSnapshotFuchsia::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_); internal::TimeZone(*snapshot_time_, dst_status, standard_offset_seconds, daylight_offset_seconds, standard_name, daylight_name); } } // namespace internal } // namespace crashpad