duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

FormatterBuffer.h (10860B)


      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  * Implements the `ZydisFormatterToken` type and provides functions to use it.
     30  */
     31 
     32 #ifndef ZYDIS_FORMATTER_TOKEN_H
     33 #define ZYDIS_FORMATTER_TOKEN_H
     34 
     35 #include <Zycore/String.h>
     36 #include <Zycore/Types.h>
     37 #include <Zydis/Defines.h>
     38 #include <Zydis/Status.h>
     39 
     40 #ifdef __cplusplus
     41 extern "C" {
     42 #endif
     43 
     44 /* ============================================================================================== */
     45 /* Constants                                                                                      */
     46 /* ============================================================================================== */
     47 
     48 /* ---------------------------------------------------------------------------------------------- */
     49 /* Token types                                                                                    */
     50 /* ---------------------------------------------------------------------------------------------- */
     51 
     52 /**
     53  * Defines the `ZydisTokenType` data-type.
     54  */
     55 typedef ZyanU8 ZydisTokenType;
     56 
     57 #define ZYDIS_TOKEN_INVALID             0x00
     58 /**
     59  * A whitespace character.
     60  */
     61 #define ZYDIS_TOKEN_WHITESPACE          0x01
     62 /**
     63  * A delimiter character (like `','`, `':'`, `'+'`, `'-'`, `'*'`).
     64  */
     65 #define ZYDIS_TOKEN_DELIMITER           0x02
     66 /**
     67  * An opening parenthesis character (like `'('`, `'['`, `'{'`).
     68  */
     69 #define ZYDIS_TOKEN_PARENTHESIS_OPEN    0x03
     70 /**
     71  * A closing parenthesis character (like `')'`, `']'`, `'}'`).
     72  */
     73 #define ZYDIS_TOKEN_PARENTHESIS_CLOSE   0x04
     74 /**
     75  * A prefix literal (like `"LOCK"`, `"REP"`).
     76  */
     77 #define ZYDIS_TOKEN_PREFIX              0x05
     78 /**
     79  * A mnemonic literal (like `"MOV"`, `"VCMPPSD"`, `"LCALL"`).
     80  */
     81 #define ZYDIS_TOKEN_MNEMONIC            0x06
     82 /**
     83  * A register literal (like `"RAX"`, `"DS"`, `"%ECX"`).
     84  */
     85 #define ZYDIS_TOKEN_REGISTER            0x07
     86 /**
     87  * An absolute address literal (like `0x00400000`).
     88  */
     89 #define ZYDIS_TOKEN_ADDRESS_ABS         0x08
     90 /**
     91  * A relative address literal (like `-0x100`).
     92  */
     93 #define ZYDIS_TOKEN_ADDRESS_REL         0x09
     94 /**
     95  * A displacement literal (like `0xFFFFFFFF`, `-0x100`, `+0x1234`).
     96  */
     97 #define ZYDIS_TOKEN_DISPLACEMENT        0x0A
     98 /**
     99  * An immediate literal (like `0xC0`, `-0x1234`, `$0x0000`).
    100  */
    101 #define ZYDIS_TOKEN_IMMEDIATE           0x0B
    102 /**
    103  * A typecast literal (like `DWORD PTR`).
    104  */
    105 #define ZYDIS_TOKEN_TYPECAST            0x0C
    106 /**
    107  * A decorator literal (like `"Z"`, `"1TO4"`).
    108  */
    109 #define ZYDIS_TOKEN_DECORATOR           0x0D
    110 /**
    111  * A symbol literal.
    112  */
    113 #define ZYDIS_TOKEN_SYMBOL              0x0E
    114 
    115 /**
    116  * The base for user-defined token types.
    117  */
    118 #define ZYDIS_TOKEN_USER                0x80
    119 
    120 /* ---------------------------------------------------------------------------------------------- */
    121 
    122 /* ============================================================================================== */
    123 /* Enums and types                                                                                */
    124 /* ============================================================================================== */
    125 
    126 /* ---------------------------------------------------------------------------------------------- */
    127 /* Token                                                                                          */
    128 /* ---------------------------------------------------------------------------------------------- */
    129 
    130 #pragma pack(push, 1)
    131 
    132 /**
    133  * Defines the `ZydisFormatterToken` struct.
    134  *
    135  * All fields in this struct should be considered as "private". Any changes may lead to unexpected
    136  * behavior.
    137  */
    138 typedef struct ZydisFormatterToken_
    139 {
    140     /**
    141      * The token type.
    142      */
    143     ZydisTokenType type;
    144     /**
    145      * An offset to the next token, or `0`.
    146      */
    147     ZyanU8 next;
    148 } ZydisFormatterToken;
    149 
    150 #pragma pack(pop)
    151 
    152 /**
    153  * Defines the `ZydisFormatterTokenConst` data-type.
    154  */
    155 typedef const ZydisFormatterToken ZydisFormatterTokenConst;
    156 
    157 /* ---------------------------------------------------------------------------------------------- */
    158 /* Buffer                                                                                         */
    159 /* ---------------------------------------------------------------------------------------------- */
    160 
    161 /**
    162  * Defines the `ZydisFormatterBuffer` struct.
    163  *
    164  * All fields in this struct should be considered as "private". Any changes may
    165  * lead to unexpected behavior.
    166  */
    167 typedef struct ZydisFormatterBuffer_
    168 {
    169     /**
    170      * `ZYAN_TRUE`, if the buffer contains a token stream or `ZYAN_FALSE, if it
    171      *  contains a simple string.
    172      */
    173     ZyanBool is_token_list;
    174     /**
    175      * The remaining capacity of the buffer.
    176      */
    177     ZyanUSize capacity;
    178     /**
    179      * The `ZyanString` instance that refers to the literal value of the most
    180      * recently added token.
    181      */
    182     ZyanString string;
    183 } ZydisFormatterBuffer;
    184 
    185 /* ---------------------------------------------------------------------------------------------- */
    186 
    187 /* ============================================================================================== */
    188 /* Exported functions                                                                             */
    189 /* ============================================================================================== */
    190 
    191 /* ---------------------------------------------------------------------------------------------- */
    192 /* Token                                                                                          */
    193 /* ---------------------------------------------------------------------------------------------- */
    194 
    195 /**
    196  * Returns the `type` and the string `value` of the given `token`.
    197  *
    198  * @param   token   A pointer to the `ZydisFormatterToken` struct.
    199  * @param   type    Receives the token type.
    200  * @param   value   Receives a pointer to the string value of the token.
    201  *
    202  * @return  A zyan status code.
    203  */
    204 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token,
    205     ZydisTokenType* type, ZyanConstCharPointer* value);
    206 
    207 /**
    208  * Obtains the next `token` linked to the passed one.
    209  *
    210  * @param   token   Receives a pointer to the next `ZydisFormatterToken` struct
    211  *                  linked to the passed one.
    212  *
    213  * @return  A zyan status code.
    214  */
    215 ZYDIS_EXPORT ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token);
    216 
    217 /* ---------------------------------------------------------------------------------------------- */
    218 /* Buffer                                                                                         */
    219 /* ---------------------------------------------------------------------------------------------- */
    220 
    221 /**
    222  * Returns the current (most recently added) token.
    223  *
    224  * @param   buffer  A pointer to the `ZydisFormatterBuffer` struct.
    225  * @param   token   Receives a pointer to the current token.
    226  *
    227  * @return  A zyan status code.
    228  *
    229  * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least
    230  * one token.
    231  */
    232 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer,
    233     ZydisFormatterTokenConst** token);
    234 
    235 /**
    236  * Returns the `ZyanString` instance associated with the given buffer.
    237  *
    238  * @param   buffer  A pointer to the `ZydisFormatterBuffer` struct.
    239  * @param   string  Receives a pointer to the `ZyanString` instance associated with the given
    240  *                  buffer.
    241  *
    242  * @return  A zyan status code.
    243  *
    244  * This function returns `ZYAN_STATUS_INVALID_OPERATION`, if the buffer does not contain at least
    245  * one token.
    246  *
    247  * The returned string always refers to the literal value of the current (most recently added)
    248  * token and will remain valid until the buffer is destroyed.
    249  */
    250 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer,
    251     ZyanString** string);
    252 
    253 /**
    254  * Appends a new token to the `buffer`.
    255  *
    256  * @param   buffer  A pointer to the `ZydisFormatterBuffer` struct.
    257  * @param   type    The type of the new token.
    258  *
    259  * @return  A zyan status code.
    260  *
    261  * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will
    262  * automatically be updated by calling this function.
    263  */
    264 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer,
    265     ZydisTokenType type);
    266 
    267 /**
    268  * Returns a snapshot of the buffer-state.
    269  *
    270  * @param   buffer  A pointer to the `ZydisFormatterBuffer` struct.
    271  * @param   state   Receives a snapshot of the buffer-state.
    272  *
    273  * @return  A zyan status code.
    274  *
    275  * Note that the buffer-state is saved inside the buffer itself and thus becomes invalid as soon
    276  * as the buffer gets overwritten or destroyed.
    277  */
    278 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer,
    279     ZyanUPointer* state);
    280 
    281 /**
    282  * Restores a previously saved buffer-state.
    283  *
    284  * @param   buffer  A pointer to the `ZydisFormatterBuffer` struct.
    285  * @param   state   The buffer-state to restore.
    286  *
    287  * @return  A zyan status code.
    288  *
    289  * All tokens added after obtaining the given `state` snapshot will be removed. This function
    290  * does NOT restore any string content.
    291  *
    292  * Note that the `ZyanString` instance returned by `ZydisFormatterBufferGetString` will
    293  * automatically be updated by calling this function.
    294  */
    295 ZYDIS_EXPORT ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer,
    296     ZyanUPointer state);
    297 
    298 /* ---------------------------------------------------------------------------------------------- */
    299 
    300 /* ============================================================================================== */
    301 
    302 #ifdef __cplusplus
    303 }
    304 #endif
    305 
    306 #endif /* ZYDIS_FORMATTER_TOKEN_H */