| // 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_ |