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 #include <Zydis/Internal/String.h>
28*1003e004SJérôme Duval #include <Zydis/FormatterBuffer.h>
29*1003e004SJérôme Duval
30*1003e004SJérôme Duval /* ============================================================================================== */
31*1003e004SJérôme Duval /* Exported functions */
32*1003e004SJérôme Duval /* ============================================================================================== */
33*1003e004SJérôme Duval
34*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
35*1003e004SJérôme Duval /* Token */
36*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
37*1003e004SJérôme Duval
ZydisFormatterTokenGetValue(const ZydisFormatterToken * token,ZydisTokenType * type,ZyanConstCharPointer * value)38*1003e004SJérôme Duval ZyanStatus ZydisFormatterTokenGetValue(const ZydisFormatterToken* token,
39*1003e004SJérôme Duval ZydisTokenType* type, ZyanConstCharPointer* value)
40*1003e004SJérôme Duval {
41*1003e004SJérôme Duval if (!token || !type || !value)
42*1003e004SJérôme Duval {
43*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
44*1003e004SJérôme Duval }
45*1003e004SJérôme Duval
46*1003e004SJérôme Duval *type = token->type;
47*1003e004SJérôme Duval *value = (ZyanConstCharPointer)((ZyanU8*)token + sizeof(ZydisFormatterToken));
48*1003e004SJérôme Duval
49*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
50*1003e004SJérôme Duval }
51*1003e004SJérôme Duval
ZydisFormatterTokenNext(ZydisFormatterTokenConst ** token)52*1003e004SJérôme Duval ZyanStatus ZydisFormatterTokenNext(ZydisFormatterTokenConst** token)
53*1003e004SJérôme Duval {
54*1003e004SJérôme Duval if (!token || !*token)
55*1003e004SJérôme Duval {
56*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
57*1003e004SJérôme Duval }
58*1003e004SJérôme Duval
59*1003e004SJérôme Duval const ZyanU8 next = (*token)->next;
60*1003e004SJérôme Duval if (!next)
61*1003e004SJérôme Duval {
62*1003e004SJérôme Duval return ZYAN_STATUS_OUT_OF_RANGE;
63*1003e004SJérôme Duval }
64*1003e004SJérôme Duval *token = (ZydisFormatterTokenConst*)((ZyanU8*)*token + sizeof(ZydisFormatterToken) + next);
65*1003e004SJérôme Duval
66*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
67*1003e004SJérôme Duval }
68*1003e004SJérôme Duval
69*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
70*1003e004SJérôme Duval /* Buffer */
71*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
72*1003e004SJérôme Duval
ZydisFormatterBufferGetToken(const ZydisFormatterBuffer * buffer,ZydisFormatterTokenConst ** token)73*1003e004SJérôme Duval ZyanStatus ZydisFormatterBufferGetToken(const ZydisFormatterBuffer* buffer,
74*1003e004SJérôme Duval ZydisFormatterTokenConst** token)
75*1003e004SJérôme Duval {
76*1003e004SJérôme Duval if (!buffer || !token)
77*1003e004SJérôme Duval {
78*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
79*1003e004SJérôme Duval }
80*1003e004SJérôme Duval
81*1003e004SJérôme Duval *token = ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1);
82*1003e004SJérôme Duval if ((*token)->type == ZYDIS_TOKEN_INVALID)
83*1003e004SJérôme Duval {
84*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_OPERATION;
85*1003e004SJérôme Duval }
86*1003e004SJérôme Duval
87*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
88*1003e004SJérôme Duval }
89*1003e004SJérôme Duval
ZydisFormatterBufferGetString(ZydisFormatterBuffer * buffer,ZyanString ** string)90*1003e004SJérôme Duval ZyanStatus ZydisFormatterBufferGetString(ZydisFormatterBuffer* buffer, ZyanString** string)
91*1003e004SJérôme Duval {
92*1003e004SJérôme Duval if (!buffer || !string)
93*1003e004SJérôme Duval {
94*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
95*1003e004SJérôme Duval }
96*1003e004SJérôme Duval
97*1003e004SJérôme Duval if (buffer->is_token_list &&
98*1003e004SJérôme Duval ((ZydisFormatterTokenConst*)buffer->string.vector.data - 1)->type == ZYDIS_TOKEN_INVALID)
99*1003e004SJérôme Duval {
100*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_OPERATION;
101*1003e004SJérôme Duval }
102*1003e004SJérôme Duval
103*1003e004SJérôme Duval ZYAN_ASSERT(buffer->string.vector.data);
104*1003e004SJérôme Duval ZYAN_ASSERT(buffer->string.vector.size);
105*1003e004SJérôme Duval
106*1003e004SJérôme Duval *string = &buffer->string;
107*1003e004SJérôme Duval
108*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
109*1003e004SJérôme Duval }
110*1003e004SJérôme Duval
ZydisFormatterBufferAppend(ZydisFormatterBuffer * buffer,ZydisTokenType type)111*1003e004SJérôme Duval ZyanStatus ZydisFormatterBufferAppend(ZydisFormatterBuffer* buffer, ZydisTokenType type)
112*1003e004SJérôme Duval {
113*1003e004SJérôme Duval if (!buffer)
114*1003e004SJérôme Duval {
115*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
116*1003e004SJérôme Duval }
117*1003e004SJérôme Duval
118*1003e004SJérôme Duval if (!buffer->is_token_list)
119*1003e004SJérôme Duval {
120*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
121*1003e004SJérôme Duval }
122*1003e004SJérôme Duval
123*1003e004SJérôme Duval const ZyanUSize len = buffer->string.vector.size;
124*1003e004SJérôme Duval ZYAN_ASSERT((len > 0) && (len < 256));
125*1003e004SJérôme Duval if (buffer->capacity <= len + sizeof(ZydisFormatterToken))
126*1003e004SJérôme Duval {
127*1003e004SJérôme Duval return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
128*1003e004SJérôme Duval }
129*1003e004SJérôme Duval
130*1003e004SJérôme Duval ZydisFormatterToken* const last = (ZydisFormatterToken*)buffer->string.vector.data - 1;
131*1003e004SJérôme Duval last->next = (ZyanU8)len;
132*1003e004SJérôme Duval
133*1003e004SJérôme Duval const ZyanUSize delta = len + sizeof(ZydisFormatterToken);
134*1003e004SJérôme Duval buffer->capacity -= delta;
135*1003e004SJérôme Duval buffer->string.vector.data = (ZyanU8*)buffer->string.vector.data + delta;
136*1003e004SJérôme Duval buffer->string.vector.size = 1;
137*1003e004SJérôme Duval buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
138*1003e004SJérôme Duval *(char*)buffer->string.vector.data = '\0';
139*1003e004SJérôme Duval
140*1003e004SJérôme Duval ZydisFormatterToken* const token = (ZydisFormatterToken*)buffer->string.vector.data - 1;
141*1003e004SJérôme Duval token->type = type;
142*1003e004SJérôme Duval token->next = 0;
143*1003e004SJérôme Duval
144*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
145*1003e004SJérôme Duval }
146*1003e004SJérôme Duval
ZydisFormatterBufferRemember(const ZydisFormatterBuffer * buffer,ZyanUPointer * state)147*1003e004SJérôme Duval ZyanStatus ZydisFormatterBufferRemember(const ZydisFormatterBuffer* buffer, ZyanUPointer* state)
148*1003e004SJérôme Duval {
149*1003e004SJérôme Duval if (!buffer || !state)
150*1003e004SJérôme Duval {
151*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
152*1003e004SJérôme Duval }
153*1003e004SJérôme Duval
154*1003e004SJérôme Duval if (buffer->is_token_list)
155*1003e004SJérôme Duval {
156*1003e004SJérôme Duval *state = (ZyanUPointer)buffer->string.vector.data;
157*1003e004SJérôme Duval } else
158*1003e004SJérôme Duval {
159*1003e004SJérôme Duval *state = (ZyanUPointer)buffer->string.vector.size;
160*1003e004SJérôme Duval }
161*1003e004SJérôme Duval
162*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
163*1003e004SJérôme Duval }
164*1003e004SJérôme Duval
ZydisFormatterBufferRestore(ZydisFormatterBuffer * buffer,ZyanUPointer state)165*1003e004SJérôme Duval ZyanStatus ZydisFormatterBufferRestore(ZydisFormatterBuffer* buffer, ZyanUPointer state)
166*1003e004SJérôme Duval {
167*1003e004SJérôme Duval if (!buffer)
168*1003e004SJérôme Duval {
169*1003e004SJérôme Duval return ZYAN_STATUS_INVALID_ARGUMENT;
170*1003e004SJérôme Duval }
171*1003e004SJérôme Duval
172*1003e004SJérôme Duval if (buffer->is_token_list)
173*1003e004SJérôme Duval {
174*1003e004SJérôme Duval const ZyanUSize delta = (ZyanUPointer)buffer->string.vector.data - state;
175*1003e004SJérôme Duval buffer->capacity += delta;
176*1003e004SJérôme Duval buffer->string.vector.data = (void*)state;
177*1003e004SJérôme Duval buffer->string.vector.size = 1; // TODO: Restore size?
178*1003e004SJérôme Duval buffer->string.vector.capacity = ZYAN_MIN(buffer->capacity, 255);
179*1003e004SJérôme Duval *(char*)buffer->string.vector.data = '\0';
180*1003e004SJérôme Duval } else
181*1003e004SJérôme Duval {
182*1003e004SJérôme Duval buffer->string.vector.size = (ZyanUSize)state;
183*1003e004SJérôme Duval ZYDIS_STRING_NULLTERMINATE(&buffer->string);
184*1003e004SJérôme Duval }
185*1003e004SJérôme Duval
186*1003e004SJérôme Duval return ZYAN_STATUS_SUCCESS;
187*1003e004SJérôme Duval }
188*1003e004SJérôme Duval
189*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
190*1003e004SJérôme Duval
191*1003e004SJérôme Duval /* ============================================================================================== */
192