blob: de875940ba86e200c6a9de0bc22554da8343e9be [file] [log] [blame] [edit]
// 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