blob: d2eda4ca3348e8590a988012e9de2903aad6eb45 [file] [log] [blame]
// Copyright 2024 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/ffx/lib/symbolize/sys/wrapper.h"
#include "src/developer/debug/zxdb/common/curl.h"
#include "src/developer/debug/zxdb/console/format_name.h"
#include "tools/symbolizer/command_line_options.h"
#include "tools/symbolizer/symbolizer.h"
#include "tools/symbolizer/symbolizer_impl.h"
extern "C" {
void symbolizer_global_init() { zxdb::Curl::GlobalInit(); }
void symbolizer_global_cleanup() { zxdb::Curl::GlobalCleanup(); }
symbolizer::SymbolizerImpl* symbolizer_new() {
symbolizer::CommandLineOptions options;
options.SetupDefaultsFromEnvironment();
return new symbolizer::SymbolizerImpl(options);
}
void symbolizer_free(symbolizer::SymbolizerImpl* symbolizer) { delete symbolizer; }
void symbolizer_reset(symbolizer::SymbolizerImpl* symbolizer) {
symbolizer::Symbolizer::ResetType type_t = symbolizer::Symbolizer::ResetType::kUnknown;
symbolizer->Reset(false, type_t);
}
void symbolizer_add_module(symbolizer::SymbolizerImpl* symbolizer, uint64_t id, const char* name,
size_t name_len, const char* build_id, size_t build_id_len) {
symbolizer->Module(id, std::string_view(name, name_len),
std::string_view(build_id, build_id_len));
}
MappingStatus symbolizer_add_mapping(symbolizer::SymbolizerImpl* symbolizer, uint64_t module_id,
uint64_t start_addr, uint64_t size, uint64_t module_offset,
const char* flags, size_t flags_len) {
auto status = symbolizer->MMap(start_addr, size, module_id, std::string_view(flags, flags_len),
module_offset);
switch (status) {
case symbolizer::SymbolizerImpl::MMapStatus::kOk:
return MappingStatus::Ok;
case symbolizer::SymbolizerImpl::MMapStatus::kInconsistentBaseAddress:
return MappingStatus::InconsistentBaseAddress;
case symbolizer::SymbolizerImpl::MMapStatus::kInvalidModuleId:
return MappingStatus::InvalidModuleId;
};
}
ResolveAddressStatus symbolizer_resolve_address(symbolizer::SymbolizerImpl* symbolizer,
uint64_t address, location_callback output,
void* output_context) {
symbolizer::SymbolizerImpl::BacktraceStatus status = symbolizer->Backtrace(
address, symbolizer::Symbolizer::AddressType::kUnknown,
[address, output, output_context](auto inline_index, auto& location, auto& module) {
symbolizer_location_t output_location;
// Store the variable at this scope so it lives as long as the callback invocation.
std::string function_name;
if (location.symbol().is_valid()) {
auto symbol = location.symbol().Get();
auto function = symbol->template As<zxdb::Function>();
// There are some functions that are not considered zxdb::Function, e.g., functions in
// vDSO and functions in crt1.S.
// TODO(https://fxbug.dev/404336927): Investigate why cast doesn't work here for some
// functions
if (function) {
function_name = zxdb::FormatFunctionName(function, {}).AsString();
} else {
function_name = symbol->GetFullName();
}
output_location.function = function_name.c_str();
output_location.function_len = function_name.size();
}
if (location.file_line().is_valid()) {
output_location.file = location.file_line().file().c_str();
output_location.file_len = location.file_line().file().size();
output_location.line = location.file_line().line();
}
if (module.name.size() > 0) {
output_location.library = module.name.c_str();
output_location.library_len = module.name.size();
}
output_location.library_offset = address - module.base + module.negative_base;
output(&output_location, output_context);
});
switch (status) {
case symbolizer::SymbolizerImpl::BacktraceStatus::kOk:
return ResolveAddressStatus::Ok;
case symbolizer::SymbolizerImpl::BacktraceStatus::kSymbolFileUnavailable:
return ResolveAddressStatus::SymbolFileUnavailable;
case symbolizer::SymbolizerImpl::BacktraceStatus::kNoOverlappingModule:
return ResolveAddressStatus::NoOverlappingModule;
}
}
}