blob: cd6798a902cd1c13043f0366711e38b2363a7a26 [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.
#ifndef SRC_DEVELOPER_DEBUG_IPC_REGISTER_DESC_H_
#define SRC_DEVELOPER_DEBUG_IPC_REGISTER_DESC_H_
#include <stdint.h>
#include <optional>
#include <string>
#include "src/lib/containers/cpp/array_view.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_ipc {
enum class Arch : uint32_t; // Forward declaration
enum class RegisterID : uint32_t; // Forward declaration.
struct Register;
enum class SpecialRegisterType {
kNone,
kIP, // Instruction Pointer
kSP, // Stack Pointer
kTP // Thread Pointer
};
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;
};
const RegisterInfo* InfoForRegister(RegisterID id);
const RegisterInfo* InfoForRegister(Arch arch, const std::string& name);
const char* RegisterIDToString(debug_ipc::RegisterID);
debug_ipc::RegisterID StringToRegisterID(const std::string&);
// Returns the register ID for the given special register.
debug_ipc::RegisterID GetSpecialRegisterID(debug_ipc::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.
containers::array_view<uint8_t> GetRegisterData(const std::vector<Register>& 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;
enum class RegisterID : uint32_t {
kUnknown = 0,
// ARMv8 (Range: 1000-1999) --------------------------------------------------
// General purpose
kARMv8_x0 = 1000,
kARMv8_x1 = 1001,
kARMv8_x2 = 1002,
kARMv8_x3 = 1003,
kARMv8_x4 = 1004,
kARMv8_x5 = 1005,
kARMv8_x6 = 1006,
kARMv8_x7 = 1007,
kARMv8_x8 = 1008,
kARMv8_x9 = 1009,
kARMv8_x10 = 1010,
kARMv8_x11 = 1011,
kARMv8_x12 = 1012,
kARMv8_x13 = 1013,
kARMv8_x14 = 1014,
kARMv8_x15 = 1015,
kARMv8_x16 = 1016,
kARMv8_x17 = 1017,
kARMv8_x18 = 1018,
kARMv8_x19 = 1019,
kARMv8_x20 = 1020,
kARMv8_x21 = 1021,
kARMv8_x22 = 1022,
kARMv8_x23 = 1023,
kARMv8_x24 = 1024,
kARMv8_x25 = 1025,
kARMv8_x26 = 1026,
kARMv8_x27 = 1027,
kARMv8_x28 = 1028,
kARMv8_x29 = 1029,
kARMv8_lr = 1030,
kARMv8_sp = 1031,
kARMv8_pc = 1032,
// This register doesn't exist in ARMv8, but it's used as an abstraction for
// accessing the PSTATE. It's functionally equivalent to SPSR_EL1.
kARMv8_cpsr = 1034,
// General-purpose aliases (low 32-bits).
kARMv8_w0 = 1035,
kARMv8_w1 = 1036,
kARMv8_w2 = 1037,
kARMv8_w3 = 1038,
kARMv8_w4 = 1039,
kARMv8_w5 = 1040,
kARMv8_w6 = 1041,
kARMv8_w7 = 1042,
kARMv8_w8 = 1043,
kARMv8_w9 = 1044,
kARMv8_w10 = 1045,
kARMv8_w11 = 1046,
kARMv8_w12 = 1047,
kARMv8_w13 = 1048,
kARMv8_w14 = 1049,
kARMv8_w15 = 1050,
kARMv8_w16 = 1051,
kARMv8_w17 = 1052,
kARMv8_w18 = 1053,
kARMv8_w19 = 1054,
kARMv8_w20 = 1055,
kARMv8_w21 = 1056,
kARMv8_w22 = 1057,
kARMv8_w23 = 1058,
kARMv8_w24 = 1059,
kARMv8_w25 = 1060,
kARMv8_w26 = 1061,
kARMv8_w27 = 1062,
kARMv8_w28 = 1063,
kARMv8_w29 = 1064,
kARMv8_w30 = 1065,
kARMv8_x30 = 1066, // Alias for "LR" above.
// Thread Pointer/ID register
kARMv8_tpidr = 1067,
// FP (None on ARMv8).
// Vector.
kARMv8_fpcr = 1100, // Control register.
kARMv8_fpsr = 1101, // Status register.
kARMv8_v0 = 1200,
kARMv8_v1 = 1201,
kARMv8_v2 = 1202,
kARMv8_v3 = 1203,
kARMv8_v4 = 1204,
kARMv8_v5 = 1205,
kARMv8_v6 = 1206,
kARMv8_v7 = 1207,
kARMv8_v8 = 1208,
kARMv8_v9 = 1209,
kARMv8_v10 = 1210,
kARMv8_v11 = 1211,
kARMv8_v12 = 1212,
kARMv8_v13 = 1213,
kARMv8_v14 = 1214,
kARMv8_v15 = 1215,
kARMv8_v16 = 1216,
kARMv8_v17 = 1217,
kARMv8_v18 = 1218,
kARMv8_v19 = 1219,
kARMv8_v20 = 1220,
kARMv8_v21 = 1221,
kARMv8_v22 = 1222,
kARMv8_v23 = 1223,
kARMv8_v24 = 1224,
kARMv8_v25 = 1225,
kARMv8_v26 = 1226,
kARMv8_v27 = 1227,
kARMv8_v28 = 1228,
kARMv8_v29 = 1229,
kARMv8_v30 = 1230,
kARMv8_v31 = 1231,
// Debug.
kARMv8_id_aa64dfr0_el1 = 1300, // Debug Feature Register 0.
kARMv8_mdscr_el1 = 1301, // Debug System Control Register.
// HW Registers.
kARMv8_dbgbcr0_el1 = 1320,
kARMv8_dbgbcr1_el1 = 1321,
kARMv8_dbgbcr2_el1 = 1322,
kARMv8_dbgbcr3_el1 = 1323,
kARMv8_dbgbcr4_el1 = 1324,
kARMv8_dbgbcr5_el1 = 1325,
kARMv8_dbgbcr6_el1 = 1326,
kARMv8_dbgbcr7_el1 = 1327,
kARMv8_dbgbcr8_el1 = 1328,
kARMv8_dbgbcr9_el1 = 1329,
kARMv8_dbgbcr10_el1 = 1330,
kARMv8_dbgbcr11_el1 = 1331,
kARMv8_dbgbcr12_el1 = 1332,
kARMv8_dbgbcr13_el1 = 1333,
kARMv8_dbgbcr14_el1 = 1334,
kARMv8_dbgbcr15_el1 = 1335,
kARMv8_dbgbvr0_el1 = 1340,
kARMv8_dbgbvr1_el1 = 1341,
kARMv8_dbgbvr2_el1 = 1342,
kARMv8_dbgbvr3_el1 = 1343,
kARMv8_dbgbvr4_el1 = 1344,
kARMv8_dbgbvr5_el1 = 1345,
kARMv8_dbgbvr6_el1 = 1346,
kARMv8_dbgbvr7_el1 = 1347,
kARMv8_dbgbvr8_el1 = 1348,
kARMv8_dbgbvr9_el1 = 1349,
kARMv8_dbgbvr10_el1 = 1350,
kARMv8_dbgbvr11_el1 = 1351,
kARMv8_dbgbvr12_el1 = 1352,
kARMv8_dbgbvr13_el1 = 1353,
kARMv8_dbgbvr14_el1 = 1354,
kARMv8_dbgbvr15_el1 = 1355,
// HW Watchpoints.
kARMv8_dbgwcr0_el1 = 1360,
kARMv8_dbgwcr1_el1 = 1361,
kARMv8_dbgwcr2_el1 = 1362,
kARMv8_dbgwcr3_el1 = 1363,
kARMv8_dbgwcr4_el1 = 1364,
kARMv8_dbgwcr5_el1 = 1365,
kARMv8_dbgwcr6_el1 = 1366,
kARMv8_dbgwcr7_el1 = 1367,
kARMv8_dbgwcr8_el1 = 1368,
kARMv8_dbgwcr9_el1 = 1369,
kARMv8_dbgwcr10_el1 = 1370,
kARMv8_dbgwcr11_el1 = 1371,
kARMv8_dbgwcr12_el1 = 1372,
kARMv8_dbgwcr13_el1 = 1373,
kARMv8_dbgwcr14_el1 = 1374,
kARMv8_dbgwcr15_el1 = 1375,
kARMv8_dbgwvr0_el1 = 1380,
kARMv8_dbgwvr1_el1 = 1381,
kARMv8_dbgwvr2_el1 = 1382,
kARMv8_dbgwvr3_el1 = 1383,
kARMv8_dbgwvr4_el1 = 1384,
kARMv8_dbgwvr5_el1 = 1385,
kARMv8_dbgwvr6_el1 = 1386,
kARMv8_dbgwvr7_el1 = 1387,
kARMv8_dbgwvr8_el1 = 1388,
kARMv8_dbgwvr9_el1 = 1389,
kARMv8_dbgwvr10_el1 = 1390,
kARMv8_dbgwvr11_el1 = 1391,
kARMv8_dbgwvr12_el1 = 1392,
kARMv8_dbgwvr13_el1 = 1393,
kARMv8_dbgwvr14_el1 = 1394,
kARMv8_dbgwvr15_el1 = 1395,
// x64 (Range: 2000-2999) ----------------------------------------------------
// General purpose
kX64_rax = 2000,
kX64_rbx = 2001,
kX64_rcx = 2002,
kX64_rdx = 2003,
kX64_rsi = 2004,
kX64_rdi = 2005,
kX64_rbp = 2006,
kX64_rsp = 2007,
kX64_r8 = 2008,
kX64_r9 = 2009,
kX64_r10 = 2010,
kX64_r11 = 2011,
kX64_r12 = 2012,
kX64_r13 = 2013,
kX64_r14 = 2014,
kX64_r15 = 2015,
kX64_rip = 2016,
kX64_rflags = 2017,
// General purpose aliases.
kX64_ah = 2018,
kX64_al = 2019,
kX64_ax = 2020,
kX64_eax = 2021,
kX64_bh = 2022,
kX64_bl = 2023,
kX64_bx = 2024,
kX64_ebx = 2025,
kX64_ch = 2026,
kX64_cl = 2027,
kX64_cx = 2028,
kX64_ecx = 2029,
kX64_dh = 2030,
kX64_dl = 2031,
kX64_dx = 2032,
kX64_edx = 2033,
kX64_si = 2034,
kX64_esi = 2035,
kX64_di = 2036,
kX64_edi = 2037,
// Segment registers
kX64_fsbase = 2038,
kX64_gsbase = 2039,
// FP (x87 FPU/MMX).
kX64_fcw = 2100, // Control word.
kX64_fsw = 2101, // Status word.
kX64_ftw = 2102, // Tag word.
// 2103 reserved
kX64_fop = 2104, // Opcode.
kX64_fip = 2105, // Instruction pointer.
kX64_fdp = 2106, // Data pointer.
// The x87/MMX state. For x87 the each "st" entry has the low 80 bits used for
// the register contents. For MMX, the low 64 bits are used.
// The higher bits are unused.
kX64_st0 = 2110,
kX64_st1 = 2111,
kX64_st2 = 2112,
kX64_st3 = 2113,
kX64_st4 = 2114,
kX64_st5 = 2115,
kX64_st6 = 2116,
kX64_st7 = 2117,
// Although these are technically vector registers, they're aliased on top of the x87 (fp*)
// registers so must be in the same category.
kX64_mm0 = 2120,
kX64_mm1 = 2121,
kX64_mm2 = 2122,
kX64_mm3 = 2123,
kX64_mm4 = 2124,
kX64_mm5 = 2125,
kX64_mm6 = 2126,
kX64_mm7 = 2127,
// Vector.
kX64_mxcsr = 2200, // Control and Status register.
// SSE/AVX (512 bit, 128- and 256-bit variants will use the low bits of these).
kX64_zmm0 = 2400,
kX64_zmm1 = 2401,
kX64_zmm2 = 2402,
kX64_zmm3 = 2403,
kX64_zmm4 = 2404,
kX64_zmm5 = 2405,
kX64_zmm6 = 2406,
kX64_zmm7 = 2407,
kX64_zmm8 = 2408,
kX64_zmm9 = 2409,
kX64_zmm10 = 2410,
kX64_zmm11 = 2411,
kX64_zmm12 = 2412,
kX64_zmm13 = 2413,
kX64_zmm14 = 2414,
kX64_zmm15 = 2415,
kX64_zmm16 = 2416,
kX64_zmm17 = 2417,
kX64_zmm18 = 2418,
kX64_zmm19 = 2419,
kX64_zmm20 = 2420,
kX64_zmm21 = 2421,
kX64_zmm22 = 2422,
kX64_zmm23 = 2423,
kX64_zmm24 = 2424,
kX64_zmm25 = 2425,
kX64_zmm26 = 2426,
kX64_zmm27 = 2427,
kX64_zmm28 = 2428,
kX64_zmm29 = 2429,
kX64_zmm30 = 2430,
kX64_zmm31 = 2431,
// Vector aliases.
kX64_xmm0 = 2432,
kX64_xmm1 = 2433,
kX64_xmm2 = 2434,
kX64_xmm3 = 2435,
kX64_xmm4 = 2436,
kX64_xmm5 = 2437,
kX64_xmm6 = 2438,
kX64_xmm7 = 2439,
kX64_xmm8 = 2440,
kX64_xmm9 = 2441,
kX64_xmm10 = 2442,
kX64_xmm11 = 2443,
kX64_xmm12 = 2444,
kX64_xmm13 = 2445,
kX64_xmm14 = 2446,
kX64_xmm15 = 2447,
kX64_xmm16 = 2448,
kX64_xmm17 = 2449,
kX64_xmm18 = 2450,
kX64_xmm19 = 2451,
kX64_xmm20 = 2452,
kX64_xmm21 = 2453,
kX64_xmm22 = 2454,
kX64_xmm23 = 2455,
kX64_xmm24 = 2456,
kX64_xmm25 = 2457,
kX64_xmm26 = 2458,
kX64_xmm27 = 2459,
kX64_xmm28 = 2460,
kX64_xmm29 = 2461,
kX64_xmm30 = 2462,
kX64_xmm31 = 2463,
kX64_ymm0 = 2464,
kX64_ymm1 = 2465,
kX64_ymm2 = 2466,
kX64_ymm3 = 2467,
kX64_ymm4 = 2468,
kX64_ymm5 = 2469,
kX64_ymm6 = 2470,
kX64_ymm7 = 2471,
kX64_ymm8 = 2472,
kX64_ymm9 = 2473,
kX64_ymm10 = 2474,
kX64_ymm11 = 2475,
kX64_ymm12 = 2476,
kX64_ymm13 = 2477,
kX64_ymm14 = 2478,
kX64_ymm15 = 2479,
kX64_ymm16 = 2480,
kX64_ymm17 = 2481,
kX64_ymm18 = 2482,
kX64_ymm19 = 2483,
kX64_ymm20 = 2484,
kX64_ymm21 = 2485,
kX64_ymm22 = 2486,
kX64_ymm23 = 2487,
kX64_ymm24 = 2488,
kX64_ymm25 = 2489,
kX64_ymm26 = 2490,
kX64_ymm27 = 2491,
kX64_ymm28 = 2492,
kX64_ymm29 = 2493,
kX64_ymm30 = 2494,
kX64_ymm31 = 2495,
// Debug.
kX64_dr0 = 2600,
kX64_dr1 = 2601,
kX64_dr2 = 2602,
kX64_dr3 = 2603,
// dr4 is reserved.
// dr5 is reserved.
kX64_dr6 = 2606,
kX64_dr7 = 2607,
};
// 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_ipc
#endif // SRC_DEVELOPER_DEBUG_IPC_REGISTER_DESC_H_