1*1003e004SJérôme Duval /*************************************************************************************************** 2*1003e004SJérôme Duval 3*1003e004SJérôme Duval Zyan Disassembler Library (Zydis) 4*1003e004SJérôme Duval 5*1003e004SJérôme Duval Original Author : Florian Bernd 6*1003e004SJérôme Duval 7*1003e004SJérôme Duval * Permission is hereby granted, free of charge, to any person obtaining a copy 8*1003e004SJérôme Duval * of this software and associated documentation files (the "Software"), to deal 9*1003e004SJérôme Duval * in the Software without restriction, including without limitation the rights 10*1003e004SJérôme Duval * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11*1003e004SJérôme Duval * copies of the Software, and to permit persons to whom the Software is 12*1003e004SJérôme Duval * furnished to do so, subject to the following conditions: 13*1003e004SJérôme Duval * 14*1003e004SJérôme Duval * The above copyright notice and this permission notice shall be included in all 15*1003e004SJérôme Duval * copies or substantial portions of the Software. 16*1003e004SJérôme Duval * 17*1003e004SJérôme Duval * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18*1003e004SJérôme Duval * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19*1003e004SJérôme Duval * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20*1003e004SJérôme Duval * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21*1003e004SJérôme Duval * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22*1003e004SJérôme Duval * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23*1003e004SJérôme Duval * SOFTWARE. 24*1003e004SJérôme Duval 25*1003e004SJérôme Duval ***************************************************************************************************/ 26*1003e004SJérôme Duval 27*1003e004SJérôme Duval /** 28*1003e004SJérôme Duval * @file 29*1003e004SJérôme Duval * Utility functions and constants for registers. 30*1003e004SJérôme Duval */ 31*1003e004SJérôme Duval 32*1003e004SJérôme Duval #ifndef ZYDIS_REGISTER_H 33*1003e004SJérôme Duval #define ZYDIS_REGISTER_H 34*1003e004SJérôme Duval 35*1003e004SJérôme Duval #include <Zycore/Defines.h> 36*1003e004SJérôme Duval #include <Zycore/Types.h> 37*1003e004SJérôme Duval #include <Zydis/Defines.h> 38*1003e004SJérôme Duval #include <Zydis/SharedTypes.h> 39*1003e004SJérôme Duval #include <Zydis/ShortString.h> 40*1003e004SJérôme Duval 41*1003e004SJérôme Duval #ifdef __cplusplus 42*1003e004SJérôme Duval extern "C" { 43*1003e004SJérôme Duval #endif 44*1003e004SJérôme Duval 45*1003e004SJérôme Duval /* ============================================================================================== */ 46*1003e004SJérôme Duval /* Enums and types */ 47*1003e004SJérôme Duval /* ============================================================================================== */ 48*1003e004SJérôme Duval 49*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 50*1003e004SJérôme Duval /* Registers */ 51*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 52*1003e004SJérôme Duval 53*1003e004SJérôme Duval #include <Zydis/Generated/EnumRegister.h> 54*1003e004SJérôme Duval 55*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 56*1003e004SJérôme Duval /* Register kinds */ 57*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 58*1003e004SJérôme Duval 59*1003e004SJérôme Duval /** 60*1003e004SJérôme Duval * Defines the `ZydisRegisterKind` enum. 61*1003e004SJérôme Duval * 62*1003e004SJérôme Duval * Please note that this enum does not contain a matching entry for all values of the 63*1003e004SJérôme Duval * `ZydisRegister` enum, but only for those registers where it makes sense to logically group them 64*1003e004SJérôme Duval * for decoding/encoding purposes. 65*1003e004SJérôme Duval * 66*1003e004SJérôme Duval * These are mainly the registers that can be identified by an id within their corresponding 67*1003e004SJérôme Duval * register-class. 68*1003e004SJérôme Duval */ 69*1003e004SJérôme Duval typedef enum ZydisRegisterKind_ 70*1003e004SJérôme Duval { 71*1003e004SJérôme Duval ZYDIS_REGKIND_INVALID, 72*1003e004SJérôme Duval ZYDIS_REGKIND_GPR, 73*1003e004SJérôme Duval ZYDIS_REGKIND_X87, 74*1003e004SJérôme Duval ZYDIS_REGKIND_MMX, 75*1003e004SJérôme Duval ZYDIS_REGKIND_VR, 76*1003e004SJérôme Duval ZYDIS_REGKIND_TMM, 77*1003e004SJérôme Duval ZYDIS_REGKIND_SEGMENT, 78*1003e004SJérôme Duval ZYDIS_REGKIND_TEST, 79*1003e004SJérôme Duval ZYDIS_REGKIND_CONTROL, 80*1003e004SJérôme Duval ZYDIS_REGKIND_DEBUG, 81*1003e004SJérôme Duval ZYDIS_REGKIND_MASK, 82*1003e004SJérôme Duval ZYDIS_REGKIND_BOUND, 83*1003e004SJérôme Duval 84*1003e004SJérôme Duval /** 85*1003e004SJérôme Duval * Maximum value of this enum. 86*1003e004SJérôme Duval */ 87*1003e004SJérôme Duval ZYDIS_REGKIND_MAX_VALUE = ZYDIS_REGKIND_BOUND, 88*1003e004SJérôme Duval /** 89*1003e004SJérôme Duval * The minimum number of bits required to represent all values of this enum. 90*1003e004SJérôme Duval */ 91*1003e004SJérôme Duval ZYDIS_REGKIND_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REGKIND_MAX_VALUE) 92*1003e004SJérôme Duval } ZydisRegisterKind; 93*1003e004SJérôme Duval 94*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 95*1003e004SJérôme Duval /* Register classes */ 96*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 97*1003e004SJérôme Duval 98*1003e004SJérôme Duval /** 99*1003e004SJérôme Duval * Defines the `ZydisRegisterClass` enum. 100*1003e004SJérôme Duval * 101*1003e004SJérôme Duval * Please note that this enum does not contain a matching entry for all values of the 102*1003e004SJérôme Duval * `ZydisRegister` enum, but only for those registers where it makes sense to logically group them 103*1003e004SJérôme Duval * for decoding/encoding purposes. 104*1003e004SJérôme Duval * 105*1003e004SJérôme Duval * These are mainly the registers that can be identified by an id within their corresponding 106*1003e004SJérôme Duval * register-class. The `IP` and `FLAGS` values are exceptions to this rule. 107*1003e004SJérôme Duval */ 108*1003e004SJérôme Duval typedef enum ZydisRegisterClass_ 109*1003e004SJérôme Duval { 110*1003e004SJérôme Duval ZYDIS_REGCLASS_INVALID, 111*1003e004SJérôme Duval /** 112*1003e004SJérôme Duval * 8-bit general-purpose registers. 113*1003e004SJérôme Duval */ 114*1003e004SJérôme Duval ZYDIS_REGCLASS_GPR8, 115*1003e004SJérôme Duval /** 116*1003e004SJérôme Duval * 16-bit general-purpose registers. 117*1003e004SJérôme Duval */ 118*1003e004SJérôme Duval ZYDIS_REGCLASS_GPR16, 119*1003e004SJérôme Duval /** 120*1003e004SJérôme Duval * 32-bit general-purpose registers. 121*1003e004SJérôme Duval */ 122*1003e004SJérôme Duval ZYDIS_REGCLASS_GPR32, 123*1003e004SJérôme Duval /** 124*1003e004SJérôme Duval * 64-bit general-purpose registers. 125*1003e004SJérôme Duval */ 126*1003e004SJérôme Duval ZYDIS_REGCLASS_GPR64, 127*1003e004SJérôme Duval /** 128*1003e004SJérôme Duval * Floating point legacy registers. 129*1003e004SJérôme Duval */ 130*1003e004SJérôme Duval ZYDIS_REGCLASS_X87, 131*1003e004SJérôme Duval /** 132*1003e004SJérôme Duval * Floating point multimedia registers. 133*1003e004SJérôme Duval */ 134*1003e004SJérôme Duval ZYDIS_REGCLASS_MMX, 135*1003e004SJérôme Duval /** 136*1003e004SJérôme Duval * 128-bit vector registers. 137*1003e004SJérôme Duval */ 138*1003e004SJérôme Duval ZYDIS_REGCLASS_XMM, 139*1003e004SJérôme Duval /** 140*1003e004SJérôme Duval * 256-bit vector registers. 141*1003e004SJérôme Duval */ 142*1003e004SJérôme Duval ZYDIS_REGCLASS_YMM, 143*1003e004SJérôme Duval /** 144*1003e004SJérôme Duval * 512-bit vector registers. 145*1003e004SJérôme Duval */ 146*1003e004SJérôme Duval ZYDIS_REGCLASS_ZMM, 147*1003e004SJérôme Duval /** 148*1003e004SJérôme Duval * Matrix registers. 149*1003e004SJérôme Duval */ 150*1003e004SJérôme Duval ZYDIS_REGCLASS_TMM, 151*1003e004SJérôme Duval /* 152*1003e004SJérôme Duval * Flags registers. 153*1003e004SJérôme Duval */ 154*1003e004SJérôme Duval ZYDIS_REGCLASS_FLAGS, 155*1003e004SJérôme Duval /** 156*1003e004SJérôme Duval * Instruction-pointer registers. 157*1003e004SJérôme Duval */ 158*1003e004SJérôme Duval ZYDIS_REGCLASS_IP, 159*1003e004SJérôme Duval /** 160*1003e004SJérôme Duval * Segment registers. 161*1003e004SJérôme Duval */ 162*1003e004SJérôme Duval ZYDIS_REGCLASS_SEGMENT, 163*1003e004SJérôme Duval /** 164*1003e004SJérôme Duval * Table registers. 165*1003e004SJérôme Duval */ 166*1003e004SJérôme Duval ZYDIS_REGCLASS_TABLE, 167*1003e004SJérôme Duval /** 168*1003e004SJérôme Duval * Test registers. 169*1003e004SJérôme Duval */ 170*1003e004SJérôme Duval ZYDIS_REGCLASS_TEST, 171*1003e004SJérôme Duval /** 172*1003e004SJérôme Duval * Control registers. 173*1003e004SJérôme Duval */ 174*1003e004SJérôme Duval ZYDIS_REGCLASS_CONTROL, 175*1003e004SJérôme Duval /** 176*1003e004SJérôme Duval * Debug registers. 177*1003e004SJérôme Duval */ 178*1003e004SJérôme Duval ZYDIS_REGCLASS_DEBUG, 179*1003e004SJérôme Duval /** 180*1003e004SJérôme Duval * Mask registers. 181*1003e004SJérôme Duval */ 182*1003e004SJérôme Duval ZYDIS_REGCLASS_MASK, 183*1003e004SJérôme Duval /** 184*1003e004SJérôme Duval * Bound registers. 185*1003e004SJérôme Duval */ 186*1003e004SJérôme Duval ZYDIS_REGCLASS_BOUND, 187*1003e004SJérôme Duval 188*1003e004SJérôme Duval /** 189*1003e004SJérôme Duval * Maximum value of this enum. 190*1003e004SJérôme Duval */ 191*1003e004SJérôme Duval ZYDIS_REGCLASS_MAX_VALUE = ZYDIS_REGCLASS_BOUND, 192*1003e004SJérôme Duval /** 193*1003e004SJérôme Duval * The minimum number of bits required to represent all values of this enum. 194*1003e004SJérôme Duval */ 195*1003e004SJérôme Duval ZYDIS_REGCLASS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REGCLASS_MAX_VALUE) 196*1003e004SJérôme Duval } ZydisRegisterClass; 197*1003e004SJérôme Duval 198*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 199*1003e004SJérôme Duval /* Register width */ 200*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 201*1003e004SJérôme Duval 202*1003e004SJérôme Duval /** 203*1003e004SJérôme Duval * Defines the `ZydisRegisterWidth` data-type. 204*1003e004SJérôme Duval */ 205*1003e004SJérôme Duval typedef ZyanU16 ZydisRegisterWidth; 206*1003e004SJérôme Duval 207*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 208*1003e004SJérôme Duval /* Register context */ 209*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 210*1003e004SJérôme Duval 211*1003e004SJérôme Duval /** 212*1003e004SJérôme Duval * Defines the `ZydisRegisterContext` struct. 213*1003e004SJérôme Duval */ 214*1003e004SJérôme Duval typedef struct ZydisRegisterContext_ 215*1003e004SJérôme Duval { 216*1003e004SJérôme Duval /** 217*1003e004SJérôme Duval * The values stored in the register context. 218*1003e004SJérôme Duval */ 219*1003e004SJérôme Duval ZyanU64 values[ZYDIS_REGISTER_MAX_VALUE + 1]; 220*1003e004SJérôme Duval } ZydisRegisterContext; 221*1003e004SJérôme Duval 222*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 223*1003e004SJérôme Duval 224*1003e004SJérôme Duval /* ============================================================================================== */ 225*1003e004SJérôme Duval /* Exported functions */ 226*1003e004SJérôme Duval /* ============================================================================================== */ 227*1003e004SJérôme Duval 228*1003e004SJérôme Duval /** 229*1003e004SJérôme Duval * @addtogroup register Register 230*1003e004SJérôme Duval * Functions allowing retrieval of information about registers. 231*1003e004SJérôme Duval * @{ 232*1003e004SJérôme Duval */ 233*1003e004SJérôme Duval 234*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 235*1003e004SJérôme Duval /* Register */ 236*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 237*1003e004SJérôme Duval 238*1003e004SJérôme Duval /** 239*1003e004SJérôme Duval * Returns the register specified by the `register_class` and `id` tuple. 240*1003e004SJérôme Duval * 241*1003e004SJérôme Duval * @param register_class The register class. 242*1003e004SJérôme Duval * @param id The register id. 243*1003e004SJérôme Duval * 244*1003e004SJérôme Duval * @return The register specified by the `register_class` and `id` tuple or `ZYDIS_REGISTER_NONE`, 245*1003e004SJérôme Duval * if an invalid parameter was passed. 246*1003e004SJérôme Duval */ 247*1003e004SJérôme Duval ZYDIS_EXPORT ZydisRegister ZydisRegisterEncode(ZydisRegisterClass register_class, ZyanU8 id); 248*1003e004SJérôme Duval 249*1003e004SJérôme Duval /** 250*1003e004SJérôme Duval * Returns the id of the specified register. 251*1003e004SJérôme Duval * 252*1003e004SJérôme Duval * @param reg The register. 253*1003e004SJérôme Duval * 254*1003e004SJérôme Duval * @return The id of the specified register, or -1 if an invalid parameter was passed. 255*1003e004SJérôme Duval */ 256*1003e004SJérôme Duval ZYDIS_EXPORT ZyanI8 ZydisRegisterGetId(ZydisRegister reg); 257*1003e004SJérôme Duval 258*1003e004SJérôme Duval /** 259*1003e004SJérôme Duval * Returns the register-class of the specified register. 260*1003e004SJérôme Duval * 261*1003e004SJérôme Duval * @param reg The register. 262*1003e004SJérôme Duval * 263*1003e004SJérôme Duval * @return The register-class of the specified register. 264*1003e004SJérôme Duval */ 265*1003e004SJérôme Duval ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg); 266*1003e004SJérôme Duval 267*1003e004SJérôme Duval /** 268*1003e004SJérôme Duval * Returns the width of the specified register. 269*1003e004SJérôme Duval * 270*1003e004SJérôme Duval * @param mode The active machine mode. 271*1003e004SJérôme Duval * @param reg The register. 272*1003e004SJérôme Duval * 273*1003e004SJérôme Duval * @return The width of the specified register, or `ZYDIS_REGISTER_NONE` if the register is 274*1003e004SJérôme Duval * invalid for the active machine-mode. 275*1003e004SJérôme Duval */ 276*1003e004SJérôme Duval ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth(ZydisMachineMode mode, ZydisRegister reg); 277*1003e004SJérôme Duval 278*1003e004SJérôme Duval /** 279*1003e004SJérôme Duval * Returns the largest enclosing register of the given register. 280*1003e004SJérôme Duval * 281*1003e004SJérôme Duval * @param mode The active machine mode. 282*1003e004SJérôme Duval * @param reg The register. 283*1003e004SJérôme Duval * 284*1003e004SJérôme Duval * @return The largest enclosing register of the given register, or `ZYDIS_REGISTER_NONE` if the 285*1003e004SJérôme Duval * register is invalid for the active machine-mode. 286*1003e004SJérôme Duval */ 287*1003e004SJérôme Duval ZYDIS_EXPORT ZydisRegister ZydisRegisterGetLargestEnclosing(ZydisMachineMode mode, 288*1003e004SJérôme Duval ZydisRegister reg); 289*1003e004SJérôme Duval 290*1003e004SJérôme Duval /** 291*1003e004SJérôme Duval * Returns the specified register string. 292*1003e004SJérôme Duval * 293*1003e004SJérôme Duval * @param reg The register. 294*1003e004SJérôme Duval * 295*1003e004SJérôme Duval * @return The register string or `ZYAN_NULL`, if an invalid register was passed. 296*1003e004SJérôme Duval */ 297*1003e004SJérôme Duval ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg); 298*1003e004SJérôme Duval 299*1003e004SJérôme Duval /** 300*1003e004SJérôme Duval * Returns the specified register string as `ZydisShortString`. 301*1003e004SJérôme Duval * 302*1003e004SJérôme Duval * @param reg The register. 303*1003e004SJérôme Duval * 304*1003e004SJérôme Duval * @return The register string or `ZYAN_NULL`, if an invalid register was passed. 305*1003e004SJérôme Duval * 306*1003e004SJérôme Duval * The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case. 307*1003e004SJérôme Duval */ 308*1003e004SJérôme Duval ZYDIS_EXPORT const ZydisShortString* ZydisRegisterGetStringWrapped(ZydisRegister reg); 309*1003e004SJérôme Duval 310*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 311*1003e004SJérôme Duval /* Register class */ 312*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 313*1003e004SJérôme Duval 314*1003e004SJérôme Duval /** 315*1003e004SJérôme Duval * Returns the width of the specified register-class. 316*1003e004SJérôme Duval * 317*1003e004SJérôme Duval * @param mode The active machine mode. 318*1003e004SJérôme Duval * @param register_class The register class. 319*1003e004SJérôme Duval * 320*1003e004SJérôme Duval * @return The width of the specified register. 321*1003e004SJérôme Duval */ 322*1003e004SJérôme Duval ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterClassGetWidth(ZydisMachineMode mode, 323*1003e004SJérôme Duval ZydisRegisterClass register_class); 324*1003e004SJérôme Duval 325*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */ 326*1003e004SJérôme Duval 327*1003e004SJérôme Duval /** 328*1003e004SJérôme Duval * @} 329*1003e004SJérôme Duval */ 330*1003e004SJérôme Duval 331*1003e004SJérôme Duval /* ============================================================================================== */ 332*1003e004SJérôme Duval 333*1003e004SJérôme Duval #ifdef __cplusplus 334*1003e004SJérôme Duval } 335*1003e004SJérôme Duval #endif 336*1003e004SJérôme Duval 337*1003e004SJérôme Duval #endif /* ZYDIS_REGISTER_H */ 338