| // 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/debug/zxdb/expr/register_utils.h" |
| |
| #include "src/developer/debug/shared/register_info.h" |
| #include "src/developer/debug/zxdb/expr/builtin_types.h" |
| #include "src/developer/debug/zxdb/expr/find_name.h" |
| #include "src/developer/debug/zxdb/symbols/modified_type.h" |
| |
| namespace zxdb { |
| |
| debug::RegisterID GetRegisterID(debug::Arch arch, const ParsedIdentifier& ident) { |
| // Check for explicit register identifier annotation. |
| if (ident.components().size() == 1 && |
| ident.components()[0].special() == SpecialIdentifier::kRegister) { |
| return debug::StringToRegisterID(arch, ident.components()[0].name()); |
| } |
| |
| // Try to convert the identifier string to a register name. |
| auto str = GetSingleComponentIdentifierName(ident); |
| if (!str) |
| return debug::RegisterID::kUnknown; |
| return debug::StringToRegisterID(arch, *str); |
| } |
| |
| Err GetUnavailableRegisterErr(debug::RegisterID id) { |
| return Err("Register %s unavailable in this context.", debug::RegisterIDToString(id)); |
| } |
| |
| ErrOrValue RegisterDataToValue(ExprLanguage lang, debug::RegisterID id, |
| VectorRegisterFormat vector_fmt, cpp20::span<const uint8_t> data) { |
| const debug::RegisterInfo* info = debug::InfoForRegister(id); |
| if (!info) |
| return Err("Unknown register"); |
| |
| ExprValueSource source(id); |
| |
| switch (info->format) { |
| case debug::RegisterFormat::kGeneral: |
| case debug::RegisterFormat::kSpecial: { |
| return ExprValue(GetBuiltinUnsignedType(lang, data.size()), |
| std::vector<uint8_t>(data.begin(), data.end()), source); |
| } |
| |
| case debug::RegisterFormat::kFloat: { |
| return ExprValue(GetBuiltinFloatType(lang, data.size()), |
| std::vector<uint8_t>(data.begin(), data.end()), source); |
| } |
| |
| case debug::RegisterFormat::kVector: { |
| return VectorRegisterToValue(id, vector_fmt, std::vector<uint8_t>(data.begin(), data.end())); |
| } |
| |
| case debug::RegisterFormat::kVoidAddress: { |
| // A void* is a pointer to no type. |
| return ExprValue(fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, LazySymbol()), |
| std::vector<uint8_t>(data.begin(), data.end()), source); |
| } |
| |
| case debug::RegisterFormat::kWordAddress: { |
| auto word_ptr_type = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, |
| GetBuiltinUnsignedType(lang, 8)); |
| return ExprValue(word_ptr_type, std::vector<uint8_t>(data.begin(), data.end()), source); |
| } |
| } |
| |
| return Err("Unknown register type"); |
| } |
| |
| } // namespace zxdb |