blob: d478d848b79cb72ea2bf7ac1caaacda78c226446 [file] [log] [blame]
// Copyright 2023 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 <lib/ld/processargs.h>
#include <lib/zircon-internal/unique-backtrace.h>
#include <string_view>
#include "zircon.h"
namespace ld {
namespace {
using namespace std::literals;
constexpr std::string_view kLdDebugPrefix = "\0LD_DEBUG="sv;
constexpr std::string_view kLdDebugPrefixFirst = kLdDebugPrefix.substr(1);
constexpr bool HasLdDebug(std::string_view env) {
std::string_view debug;
if (env.starts_with(kLdDebugPrefixFirst)) {
debug = env.substr(kLdDebugPrefixFirst.size());
} else if (size_t found = env.find(kLdDebugPrefix); found != std::string_view::npos) {
debug = env.substr(found + kLdDebugPrefix.size());
}
return !debug.empty() && debug.front() != '\0';
}
} // namespace
StartupData ReadBootstrap(zx::unowned_channel bootstrap) {
StartupData startup;
ProcessargsBuffer<> message;
ProcessargsBuffer<>::HandlesBuffer handles_buffer;
zx::result read = message.Read(bootstrap->borrow(), handles_buffer);
if (read.is_error()) [[unlikely]] {
CRASH_WITH_UNIQUE_BACKTRACE();
}
std::span handles = std::span{handles_buffer}.subspan(0, read->handles);
const std::span handle_info = message.handle_info(read->handles);
if (!message.Valid(*read)) [[unlikely]] {
CRASH_WITH_UNIQUE_BACKTRACE();
}
for (uint32_t i = 0; i < handles.size(); ++i) {
// If not otherwise consumed below, the handle will be closed.
zx::handle handle{std::exchange(handles[i], {})};
switch (PA_HND_TYPE(handle_info[i])) {
case PA_VMAR_ROOT:
startup.vmar.reset(handle.release());
break;
case PA_VMAR_LOADED:
startup.self_vmar.reset(handle.release());
break;
case PA_VMO_EXECUTABLE:
startup.executable_vmo.reset(handle.release());
break;
case PA_FD:
if (ld::IsProcessargsLogHandle(handle_info[i])) {
startup.log.TakeLogHandle(std::move(handle));
}
break;
case PA_LDSVC_LOADER:
startup.ldsvc.reset(handle.release());
break;
default: // Other handles are not interesting and get dropped.
break;
}
}
// The only part of the strings of interest is the environment, and only to
// search it for LD_DEBUG rather than finding all the individual strings.
startup.ld_debug = HasLdDebug(message.environ_chars(read->bytes));
return startup;
}
} // namespace ld