| // 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. | |
| #ifndef SRC_DEVELOPER_DEBUG_SHARED_REGISTER_INFO_H_ | |
| #define SRC_DEVELOPER_DEBUG_SHARED_REGISTER_INFO_H_ | |
| #include <span> | |
| #include <stdint.h> | |
| #include <optional> | |
| #include <string> | |
| #include "src/developer/debug/shared/arch.h" | |
| #include "src/developer/debug/shared/register_id.h" | |
| #include "src/developer/debug/shared/register_value.h" | |
| // Holds constant description values for all the register data for all the | |
| // supported architectures. | |
| // The enum definitions mirror the structs defined in the debug information | |
| // for zircon (see zircon/system/public/zircon/syscalls/debug.h). | |
| namespace debug { | |
| enum class SpecialRegisterType { | |
| kNone, | |
| kIP, // Instruction Pointer | |
| kSP, // Stack Pointer | |
| kTP // Thread Pointer | |
| }; | |
| // Note that we separate out "void" addresses and "word" addresses so the debugger frontend can | |
| // assign types to register values when appropriate. | |
| enum class RegisterFormat { | |
| kGeneral, // General register that might hold any integer or an address. | |
| kFloat, // Floating-point number. | |
| kVector, // Vector registers that hold multiple values. | |
| kVoidAddress, // Registers that point to void*. | |
| kWordAddress, // Registers that point to uint64_t. | |
| kSpecial, // Things like flag registers that neither hold addresses nor numbers. | |
| }; | |
| struct RegisterInfo { | |
| RegisterID id; | |
| std::string name; | |
| Arch arch; | |
| // Some registers refer to a subset of another register, e.g. "al" (low byte of "rax") on X86 or | |
| // "w0" (low 32-bits of "x0") on ARM. This ID will be the larger canonical ID. For registers that | |
| // are themselves canonical, this will be the same as "id". | |
| RegisterID canonical_id; | |
| // When asking for a name-to-register mapping, sometimes they map to a part of a register. For | |
| // example "al" on x64 is the low 8 bits of rax. These will both be 0 for the "canonical" register | |
| // record. | |
| // | |
| // Currently these both must be a multiple of 8 for GetRegisterData() below. | |
| int bits = 0; | |
| int shift = 0; // How many bits shited to the right is the low bit of the value. | |
| // DWARF register ID if there is one. | |
| static constexpr uint32_t kNoDwarfId = 0xffffffff; | |
| uint32_t dwarf_id = kNoDwarfId; | |
| RegisterFormat format = RegisterFormat::kGeneral; | |
| }; | |
| const RegisterInfo* InfoForRegister(RegisterID id); | |
| const RegisterInfo* InfoForRegister(Arch arch, const std::string& name); | |
| const char* RegisterIDToString(RegisterID); | |
| RegisterID StringToRegisterID(Arch arch, const std::string&); | |
| // Returns the register ID for the given special register. | |
| RegisterID GetSpecialRegisterID(Arch, SpecialRegisterType); | |
| // Returns the special register type for a register ID. | |
| SpecialRegisterType GetSpecialRegisterType(RegisterID id); | |
| // Converts the ID number used by DWARF to our register info. Returns null if not found. | |
| const RegisterInfo* DWARFToRegisterInfo(Arch, uint32_t dwarf_reg_id); | |
| // Find out what arch a register ID belongs to | |
| Arch GetArchForRegisterID(RegisterID); | |
| // Returns true if the given register is a "general" register. General | |
| // registers are sent as part of the unwind frame data. Other registers must | |
| // be requested specially from the target. | |
| bool IsGeneralRegister(RegisterID); | |
| // Gets the data for the given register from the array. | |
| // | |
| // This does two things. It searches for either the requested register or the canonical register. | |
| // If it's a different canonical register (like you're asking for the a 32 bits pseudoregister out | |
| // of a 64 bit register), the relevant bits will be extracted. | |
| // | |
| // If found, the return value will be the range of data within the data owned by |regs| | |
| // corresponding to the requested register. If the source data is truncated, the result will be | |
| // truncated also so it may have less data than expected. | |
| // | |
| // If the register is not found, the returned view will be empty. | |
| std::span<const uint8_t> GetRegisterData(const std::vector<RegisterValue>& regs, RegisterID id); | |
| // These ranges permit to make transformation from registerID to category and | |
| // make some formal verifications. | |
| constexpr uint32_t kARMv8GeneralBegin = 1000; | |
| constexpr uint32_t kARMv8GeneralEnd = 1099; | |
| constexpr uint32_t kARMv8VectorBegin = 1100; | |
| constexpr uint32_t kARMv8VectorEnd = 1299; | |
| constexpr uint32_t kARMv8DebugBegin = 1300; | |
| constexpr uint32_t kARMv8DebugEnd = 1399; | |
| constexpr uint32_t kX64GeneralBegin = 2000; | |
| constexpr uint32_t kX64GeneralEnd = 2099; | |
| constexpr uint32_t kX64FPBegin = 2100; | |
| constexpr uint32_t kX64FPEnd = 2199; | |
| constexpr uint32_t kX64VectorBegin = 2200; | |
| constexpr uint32_t kX64VectorEnd = 2599; | |
| constexpr uint32_t kX64DebugBegin = 2600; | |
| constexpr uint32_t kX64DebugEnd = 2699; | |
| constexpr uint32_t kRiscv64GeneralBegin = 3000; | |
| constexpr uint32_t kRiscv64GeneralEnd = 3099; | |
| constexpr uint32_t kRiscv64FPBegin = 3100; | |
| constexpr uint32_t kRiscv64FPEnd = 3299; | |
| constexpr uint32_t kRiscv64VectorBegin = 3300; | |
| constexpr uint32_t kRiscv64VectorEnd = 3599; | |
| constexpr uint32_t kRiscv64DebugBegin = 3600; | |
| constexpr uint32_t kRiscv64DebugEnd = 3699; | |
| // Categories -------------------------------------------------------------------------------------- | |
| enum class RegisterCategory : uint32_t { | |
| kNone = 0, | |
| kGeneral, | |
| kFloatingPoint, | |
| kVector, | |
| kDebug, | |
| kLast, // Not an element, for marking the max size. | |
| }; | |
| const char* RegisterCategoryToString(RegisterCategory); | |
| RegisterCategory RegisterIDToCategory(RegisterID); | |
| } // namespace debug | |
| #endif // SRC_DEVELOPER_DEBUG_SHARED_REGISTER_INFO_H_ |