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