blob: 9ffe0d09fdbab2c92a69c08203394477117ee685 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/debug_agent/zircon_system_interface.h"
#include <fuchsia/kernel/cpp/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include "src/developer/debug/debug_agent/zircon_binary_launcher.h"
#include "src/developer/debug/debug_agent/zircon_job_handle.h"
#include "src/developer/debug/debug_agent/zircon_process_handle.h"
#include "src/developer/debug/debug_agent/zircon_utils.h"
#include "src/lib/files/file.h"
namespace debug_agent {
namespace {
// Returns an !is_valid() job object on failure.
zx::job GetRootZxJob() {
zx::job root_job;
fuchsia::kernel::RootJobSyncPtr root_job_ptr;
std::string root_job_path("/svc/");
root_job_path.append(fuchsia::kernel::RootJob::Name_);
zx_status_t status = fdio_service_connect(root_job_path.c_str(),
root_job_ptr.NewRequest().TakeChannel().release());
if (status != ZX_OK) {
FX_NOTREACHED();
return zx::job();
}
status = root_job_ptr->Get(&root_job);
if (status != ZX_OK) {
FX_NOTREACHED();
return zx::job();
}
return root_job;
}
// The hub writes the job it uses to create components in a special file.
//
// This is note quite correct. This code actually returns the job that contains the debug agent
// itself, which is usually the right thing because the debug agent normally runs in the component
// root.
//
// TODO: Find the correct job even when the debug agent is run from elsewhere.
zx_koid_t GetComponentRootJobKoid() {
// TODO(bug 56725) this function seems to no longer work and the job-id file is not found.
std::string koid_str;
bool file_read = files::ReadFileToString("/hub/job-id", &koid_str);
if (!file_read)
return ZX_KOID_INVALID;
char* end = NULL;
uint64_t koid = strtoul(koid_str.c_str(), &end, 10);
if (*end)
return ZX_KOID_INVALID;
return koid;
}
} // namespace
ZirconSystemInterface::ZirconSystemInterface()
: services_(sys::ServiceDirectory::CreateFromNamespace()),
component_manager_(services_),
limbo_provider_(services_) {
if (zx::job zx_root = GetRootZxJob(); zx_root.is_valid())
root_job_ = std::make_unique<ZirconJobHandle>(std::move(zx_root));
}
uint32_t ZirconSystemInterface::GetNumCpus() const { return zx_system_get_num_cpus(); }
uint64_t ZirconSystemInterface::GetPhysicalMemory() const { return zx_system_get_physmem(); }
std::unique_ptr<JobHandle> ZirconSystemInterface::GetRootJob() const {
if (root_job_)
return std::make_unique<ZirconJobHandle>(*root_job_);
return nullptr;
}
std::unique_ptr<JobHandle> ZirconSystemInterface::GetComponentRootJob() const {
if (!root_job_)
return nullptr;
zx_koid_t component_root_koid = GetComponentRootJobKoid();
if (component_root_koid == ZX_KOID_INVALID)
return nullptr;
return root_job_->FindJob(component_root_koid);
}
std::unique_ptr<BinaryLauncher> ZirconSystemInterface::GetLauncher() const {
return std::make_unique<ZirconBinaryLauncher>(services_);
}
ComponentManager& ZirconSystemInterface::GetComponentManager() { return component_manager_; }
std::string ZirconSystemInterface::GetSystemVersion() { return zx_system_get_version_string(); }
} // namespace debug_agent