| // Copyright 2023 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "libhwsec/factory/instr_profiling.h" | |
| #include <string> | |
| #include <base/files/file_path.h> | |
| #include <base/files/file_util.h> | |
| #include <base/logging.h> | |
| #include <base/rand_util.h> | |
| #include <base/strings/string_util.h> | |
| #if ENABLE_PROFILING | |
| extern "C" { | |
| int __llvm_profile_runtime; | |
| void __llvm_profile_set_filename(const char*); | |
| int __llvm_profile_write_file(void); | |
| } | |
| #endif | |
| namespace hwsec::register_profiling { | |
| #if ENABLE_PROFILING | |
| namespace { | |
| constexpr char kProfileFileDir[] = | |
| "/mnt/stateful_partition/unencrypted/profraws"; | |
| constexpr char kProfileFileSuffix[] = "-libhwsec-%m-%p.profraw"; | |
| constexpr char kProcessCommandNameFilename[] = "/proc/self/comm"; | |
| constexpr char kDefaultPrefix[] = "UNKNOWN"; | |
| std::optional<std::string> GetProcessCommandName() { | |
| std::string name; | |
| if (!base::ReadFileToString(base::FilePath(kProcessCommandNameFilename), | |
| &name)) { | |
| return {}; | |
| } | |
| // Remove the characters we are not interested in, e.g., new line character. | |
| base::TrimWhitespaceASCII(name, base::TRIM_TRAILING, &name); | |
| return name; | |
| } | |
| std::string ConstructFilename() { | |
| // Get a random uint64_t. It helps maintaining unique profraw filenames. | |
| std::string random_int = std::to_string(base::RandUint64()); | |
| // Get current process name. | |
| std::string process_name = GetProcessCommandName().value_or(kDefaultPrefix); | |
| // Build the entire string. | |
| const base::FilePath filename = | |
| base::FilePath(kProfileFileDir) | |
| .Append(base::FilePath(process_name + "-" + random_int + | |
| kProfileFileSuffix)); | |
| return filename.value(); | |
| } | |
| } // namespace | |
| void SetUp() { | |
| __llvm_profile_set_filename(ConstructFilename().c_str()); | |
| } | |
| void End() { | |
| __llvm_profile_write_file(); | |
| } | |
| #else | |
| void SetUp() { | |
| // no-ops | |
| } | |
| void End() { | |
| // no-ops | |
| } | |
| #endif | |
| } // namespace hwsec::register_profiling |