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  * @brief   Utility functions and constants for registers.
30  */
31 
32 #ifndef ZYDIS_REGISTER_H
33 #define ZYDIS_REGISTER_H
34 
35 #include "zydis/Zycore/Defines.h"
36 #include "zydis/Zycore/Types.h"
37 #include "zydis/Zydis/SharedTypes.h"
38 #include "zydis/Zydis/ShortString.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /* ============================================================================================== */
45 /* Enums and types                                                                                */
46 /* ============================================================================================== */
47 
48 /* ---------------------------------------------------------------------------------------------- */
49 /* Registers                                                                                      */
50 /* ---------------------------------------------------------------------------------------------- */
51 
52 #include "zydis/Zydis/Generated/EnumRegister.h"
53 
54 /* ---------------------------------------------------------------------------------------------- */
55 /* Register classes                                                                               */
56 /* ---------------------------------------------------------------------------------------------- */
57 
58 /**
59  * @brief   Defines the `ZydisRegisterClass` enum.
60  *
61  * Please note that this enum does not contain a matching entry for all values of the
62  * `ZydisRegister` enum, but only for those registers where it makes sense to logically group them
63  * for decoding/encoding purposes.
64  *
65  * These are mainly the registers that can be identified by an id within their corresponding
66  * register-class. The `IP` and `FLAGS` values are exceptions to this rule.
67  */
68 typedef enum ZydisRegisterClass_
69 {
70     ZYDIS_REGCLASS_INVALID,
71     /**
72      * @brief   8-bit general-purpose registers.
73      */
74     ZYDIS_REGCLASS_GPR8,
75     /**
76      * @brief   16-bit general-purpose registers.
77      */
78     ZYDIS_REGCLASS_GPR16,
79     /**
80      * @brief   32-bit general-purpose registers.
81      */
82     ZYDIS_REGCLASS_GPR32,
83     /**
84      * @brief   64-bit general-purpose registers.
85      */
86     ZYDIS_REGCLASS_GPR64,
87     /**
88      * @brief   Floating point legacy registers.
89      */
90     ZYDIS_REGCLASS_X87,
91     /**
92      * @brief   Floating point multimedia registers.
93      */
94     ZYDIS_REGCLASS_MMX,
95     /**
96      * @brief   128-bit vector registers.
97      */
98     ZYDIS_REGCLASS_XMM,
99     /**
100      * @brief   256-bit vector registers.
101      */
102     ZYDIS_REGCLASS_YMM,
103     /**
104      * @brief   512-bit vector registers.
105      */
106     ZYDIS_REGCLASS_ZMM,
107     /**
108      * @brief   Flags registers.
109      */
110     ZYDIS_REGCLASS_FLAGS,
111     /**
112      * @brief   Instruction-pointer registers.
113      */
114     ZYDIS_REGCLASS_IP,
115     /**
116      * @brief   Segment registers.
117      */
118     ZYDIS_REGCLASS_SEGMENT,
119     /**
120      * @brief   Test registers.
121      */
122     ZYDIS_REGCLASS_TEST,
123     /**
124      * @brief   Control registers.
125      */
126     ZYDIS_REGCLASS_CONTROL,
127     /**
128      * @brief   Debug registers.
129      */
130     ZYDIS_REGCLASS_DEBUG,
131     /**
132      * @brief   Mask registers.
133      */
134     ZYDIS_REGCLASS_MASK,
135     /**
136      * @brief   Bound registers.
137      */
138     ZYDIS_REGCLASS_BOUND,
139 
140     /**
141      * @brief   Maximum value of this enum.
142      */
143     ZYDIS_REGCLASS_MAX_VALUE = ZYDIS_REGCLASS_BOUND,
144     /**
145      * @brief   The minimum number of bits required to represent all values of this enum.
146      */
147     ZYDIS_REGCLASS_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_REGCLASS_MAX_VALUE)
148 } ZydisRegisterClass;
149 
150 /* ---------------------------------------------------------------------------------------------- */
151 /* Register width                                                                                 */
152 /* ---------------------------------------------------------------------------------------------- */
153 
154 /**
155  * @brief   Defines the `ZydisRegisterWidth` data-type.
156  */
157 typedef ZyanU16 ZydisRegisterWidth;
158 
159 /* ---------------------------------------------------------------------------------------------- */
160 /* Register context                                                                               */
161 /* ---------------------------------------------------------------------------------------------- */
162 
163 /**
164  * @brief   Defines the `ZydisRegisterContext` struct.
165  */
166 typedef struct ZydisRegisterContext_
167 {
168     /**
169      * @brief   The values stored in the register context.
170      */
171     ZyanU64 values[ZYDIS_REGISTER_MAX_VALUE + 1];
172 } ZydisRegisterContext;
173 
174 /* ---------------------------------------------------------------------------------------------- */
175 
176 /* ============================================================================================== */
177 /* Exported functions                                                                             */
178 /* ============================================================================================== */
179 
180 /**
181  * @addtogroup register Register
182  * @brief Functions allowing retrieval of information about registers.
183  * @{
184  */
185 
186 /* ---------------------------------------------------------------------------------------------- */
187 /* Register                                                                                       */
188 /* ---------------------------------------------------------------------------------------------- */
189 
190 /**
191  * @brief   Returns the register specified by the `register_class` and `id` tuple.
192  *
193  * @param   register_class  The register class.
194  * @param   id              The register id.
195  *
196  * @return  The register specified by the `register_class` and `id` tuple or `ZYDIS_REGISTER_NONE`,
197  *          if an invalid parameter was passed.
198  */
199 ZYDIS_EXPORT ZydisRegister ZydisRegisterEncode(ZydisRegisterClass register_class, ZyanU8 id);
200 
201 /**
202  * @brief   Returns the id of the specified register.
203  *
204  * @param   reg The register.
205  *
206  * @return  The id of the specified register, or -1 if an invalid parameter was passed.
207  */
208 ZYDIS_EXPORT ZyanI8 ZydisRegisterGetId(ZydisRegister reg);
209 
210 /**
211  * @brief   Returns the register-class of the specified register.
212  *
213  * @param   reg The register.
214  *
215  * @return  The register-class of the specified register.
216  */
217 ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg);
218 
219 /**
220  * @brief   Returns the width of the specified register.
221  *
222  * @param   mode    The active machine mode.
223  * @param   reg     The register.
224  *
225  * @return  The width of the specified register, or `ZYDIS_REGISTER_NONE` if the register is
226  *          invalid for the active machine-mode.
227  */
228 ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth(ZydisMachineMode mode, ZydisRegister reg);
229 
230 /**
231  * @brief   Returns the largest enclosing register of the given register.
232  *
233  * @param   mode    The active machine mode.
234  * @param   reg     The register.
235  *
236  * @return  The largest enclosing register of the given register, or `ZYDIS_REGISTER_NONE` if the
237  *          register is invalid for the active machine-mode or does not have an enclosing-register.
238  */
239 ZYDIS_EXPORT ZydisRegister ZydisRegisterGetLargestEnclosing(ZydisMachineMode mode,
240     ZydisRegister reg);
241 
242 /**
243  * @brief   Returns the specified register string.
244  *
245  * @param   reg The register.
246  *
247  * @return  The register string or `ZYAN_NULL`, if an invalid register was passed.
248  */
249 ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg);
250 
251 /**
252  * @brief   Returns the specified register string as `ZydisShortString`.
253  *
254  * @param   reg The register.
255  *
256  * @return  The register string or `ZYAN_NULL`, if an invalid register was passed.
257  *
258  * The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case.
259  */
260 ZYDIS_EXPORT const ZydisShortString* ZydisRegisterGetStringWrapped(ZydisRegister reg);
261 
262 /* ---------------------------------------------------------------------------------------------- */
263 /* Register class                                                                                 */
264 /* ---------------------------------------------------------------------------------------------- */
265 
266 /**
267  * @brief   Returns the width of the specified register-class.
268  *
269  * @param   mode            The active machine mode.
270  * @param   register_class  The register class.
271  *
272  * @return  The width of the specified register.
273  */
274 ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterClassGetWidth(ZydisMachineMode mode,
275     ZydisRegisterClass register_class);
276 
277 /* ---------------------------------------------------------------------------------------------- */
278 
279 /**
280  * @}
281  */
282 
283 /* ============================================================================================== */
284 
285 #ifdef __cplusplus
286 }
287 #endif
288 
289 #endif /* ZYDIS_REGISTER_H */
290