blob: ca0784d44483e432c131f19014dc75bb86117ca6 [file] [log] [blame]
// Copyright 2018 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/zxdb/symbols/mock_symbol_data_provider.h"
#include <inttypes.h>
#include <algorithm>
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/lib/fxl/strings/string_printf.h"
namespace zxdb {
MockSymbolDataProvider::MockSymbolDataProvider() : weak_factory_(this) {}
void MockSymbolDataProvider::AddRegisterValue(debug_ipc::RegisterID id, bool synchronous,
uint64_t value) {
std::vector<uint8_t> data;
data.resize(sizeof(value));
memcpy(&data[0], &value, sizeof(value));
regs_[id] = RegData(synchronous, std::move(data));
}
void MockSymbolDataProvider::AddRegisterValue(debug_ipc::RegisterID id, bool synchronous,
std::vector<uint8_t> value) {
regs_[id] = RegData(synchronous, std::move(value));
}
void MockSymbolDataProvider::AddMemory(uint64_t address, std::vector<uint8_t> data) {
memory_.AddMemory(address, std::move(data));
}
debug_ipc::Arch MockSymbolDataProvider::GetArch() { return debug_ipc::Arch::kArm64; }
std::optional<containers::array_view<uint8_t>> MockSymbolDataProvider::GetRegister(
debug_ipc::RegisterID id) {
if (GetSpecialRegisterType(id) == debug_ipc::SpecialRegisterType::kIP) {
const uint8_t* ip_as_char = reinterpret_cast<const uint8_t*>(&ip_);
return containers::array_view(ip_as_char, ip_as_char + sizeof(ip_));
}
const auto& found = regs_.find(id);
if (found == regs_.end())
return containers::array_view<uint8_t>(); // Known to be unknown.
if (!found->second.synchronous)
return std::nullopt;
return found->second.value;
}
void MockSymbolDataProvider::GetRegisterAsync(debug_ipc::RegisterID id,
GetRegisterCallback callback) {
debug_ipc::MessageLoop::Current()->PostTask(
FROM_HERE,
[callback = std::move(callback), weak_provider = weak_factory_.GetWeakPtr(), id]() mutable {
if (!weak_provider) {
// Destroyed before callback ready.
return;
}
const auto& found = weak_provider->regs_.find(id);
if (found == weak_provider->regs_.end())
callback(Err("Failed"), {});
callback(Err(), found->second.value);
});
}
void MockSymbolDataProvider::WriteRegister(debug_ipc::RegisterID id, std::vector<uint8_t> data,
WriteCallback cb) {
register_writes_.emplace_back(id, std::move(data));
// Declare success.
debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE,
[cb = std::move(cb)]() mutable { cb(Err()); });
}
std::optional<uint64_t> MockSymbolDataProvider::GetFrameBase() { return bp_; }
void MockSymbolDataProvider::GetFrameBaseAsync(GetFrameBaseCallback callback) {
debug_ipc::MessageLoop::Current()->PostTask(
FROM_HERE,
[callback = std::move(callback), weak_provider = weak_factory_.GetWeakPtr()]() mutable {
if (!weak_provider) {
// Destroyed before callback ready.
return;
}
callback(Err(), weak_provider->bp_);
});
}
std::optional<uint64_t> MockSymbolDataProvider::GetDebugAddressForContext(
const SymbolContext&) const {
return 0;
}
void MockSymbolDataProvider::GetTLSSegment(const SymbolContext& /*symbol_context*/,
GetTLSSegmentCallback cb) {
debug_ipc::MessageLoop::Current()->PostTask(
FROM_HERE, [cb = std::move(cb), tls_segment = tls_segment_]() mutable { cb(tls_segment); });
}
uint64_t MockSymbolDataProvider::GetCanonicalFrameAddress() const { return cfa_; }
void MockSymbolDataProvider::GetMemoryAsync(uint64_t address, uint32_t size,
GetMemoryCallback callback) {
std::vector<uint8_t> result = memory_.ReadMemory(address, size);
debug_ipc::MessageLoop::Current()->PostTask(
FROM_HERE, [callback = std::move(callback), result]() mutable { callback(Err(), result); });
}
void MockSymbolDataProvider::WriteMemory(uint64_t address, std::vector<uint8_t> data,
WriteCallback cb) {
memory_writes_.emplace_back(address, std::move(data));
// Declare success.
debug_ipc::MessageLoop::Current()->PostTask(FROM_HERE,
[cb = std::move(cb)]() mutable { cb(Err()); });
}
} // namespace zxdb