@@ -46,7 +46,7 @@ This library is licensed under the BSD license. See the file COPYING.
4646#ifndef DISTORM_LIGHT
4747
4848/* Helper function to concatenate an explicit size when it's unknown from the operands. */
49- static void distorm_format_size (_WString * str , const _DInst * di , int opNum )
49+ static void distorm_format_size (unsigned char * * str , const _DInst * di , int opNum )
5050{
5151 int isSizingRequired = 0 ;
5252 /*
@@ -93,22 +93,22 @@ static void distorm_format_size(_WString* str, const _DInst* di, int opNum)
9393
9494 if (isSizingRequired )
9595 {
96- switch (di -> ops [opNum ].size )
96+ switch (di -> ops [opNum ].size / 8 )
9797 {
98- case 0 : break ; /* OT_MEM's unknown size. */
99- case 8 : strcat_WSN (str , "BYTE " ); break ;
100- case 16 : strcat_WSN (str , "WORD " ); break ;
101- case 32 : strcat_WSN (str , "DWORD " ); break ;
102- case 64 : strcat_WSN (str , "QWORD " ); break ;
103- case 80 : strcat_WSN (str , "TBYTE " ); break ;
104- case 128 : strcat_WSN (str , "DQWORD " ); break ;
105- case 256 : strcat_WSN (str , "YWORD " ); break ;
106- default : /* Big oh uh if it gets here. */ break ;
98+ /* case 0: break; /* OT_MEM's unknown size. */
99+ case 1 : strcat_WSN (str , "BYTE " ); break ;
100+ case 2 : strcat_WSN (str , "WORD " ); break ;
101+ case 4 : strcat_WSN (str , "DWORD " ); break ;
102+ case 8 : strcat_WSN (str , "QWORD " ); break ;
103+ case 10 : strcat_WSN (str , "TBYTE " ); break ;
104+ case 16 : strcat_WSN (str , "DQWORD " ); break ;
105+ case 32 : strcat_WSN (str , "YWORD " ); break ;
106+ /* default: /* Big oh uh if it gets here. */ break ;
107107 }
108108 }
109109}
110110
111- static void distorm_format_signed_disp (_WString * str , const _DInst * di , uint64_t addrMask )
111+ static void distorm_format_signed_disp (unsigned char * * str , const _DInst * di , uint64_t addrMask )
112112{
113113 int64_t tmpDisp64 ;
114114
@@ -128,11 +128,10 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
128128 _DLLEXPORT_ void distorm_format32 (const _CodeInfo * ci , const _DInst * di , _DecodedInst * result )
129129#endif
130130{
131- _WString * str ;
132- unsigned int i , isDefault ;
131+ unsigned char * str ;
132+ unsigned int i ;
133133 int64_t tmpDisp64 ;
134134 uint64_t addrMask = (uint64_t )-1 ;
135- uint8_t segment ;
136135 const _WMnemonic * mnemonic ;
137136 unsigned int suffixSize = 0 ;
138137
@@ -143,6 +142,8 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
143142 /* Gotta have full address for (di->addr - ci->codeOffset) to work in all modes. */
144143 str_hex (& result -> instructionHex , (const char * )& ci -> code [(unsigned int )(di -> addr - ci -> codeOffset )], di -> size );
145144
145+ strfinalize_WS (& result -> operands , (unsigned char * )& result -> operands .p );
146+
146147 if (di -> flags == FLAG_NOT_DECODABLE ) {
147148 /* In-place considerations: DI is RESULT. Deref fields first. */
148149 unsigned int size = di -> size ;
@@ -151,16 +152,13 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
151152
152153 result -> offset = offset ;
153154 result -> size = size ;
154- strclear_WS (& result -> operands );
155- strcpy_WSN (& result -> mnemonic , "DB " );
156- str_int (& result -> mnemonic , byte );
155+ str = (unsigned char * )& result -> mnemonic .p ;
156+ strcat_WSN (& str , "DB " );
157+ str_int (& str , byte );
158+ strfinalize_WS (& result -> mnemonic , str );
157159 return ; /* Skip to next instruction. */
158160 }
159161
160- /* Format operands: */
161- str = & result -> operands ;
162- strclear_WS (str );
163-
164162 /* Special treatment for String (movs, cmps, stos, lods, scas) instructions. */
165163 if ((di -> opcode >= I_MOVS ) && (di -> opcode <= I_SCAS )) {
166164 /*
@@ -174,46 +172,51 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
174172 }
175173 }
176174
175+ str = (unsigned char * )& result -> operands .p ;
176+
177177 for (i = 0 ; ((i < OPERANDS_NO ) && (di -> ops [i ].type != O_NONE )); i ++ ) {
178- if (i > 0 ) strcat_WSN (str , ", " );
178+ if (i > 0 ) strcat_WSN (& str , ", " );
179179 switch (di -> ops [i ].type )
180180 {
181181 case O_REG :
182- strcat_WSR (str , & _REGISTERS [di -> ops [i ].index ]);
182+ strcat_WSR (& str , & _REGISTERS [di -> ops [i ].index ]);
183183 break ;
184184 case O_IMM :
185185 /* If the instruction is 'push', show explicit size (except byte imm). */
186- if ((di -> opcode == I_PUSH ) && (di -> ops [i ].size != 8 )) distorm_format_size (str , di , i );
186+ if ((di -> opcode == I_PUSH ) && (di -> ops [i ].size != 8 )) distorm_format_size (& str , di , i );
187187 /* Special fix for negative sign extended immediates. */
188188 if ((di -> flags & FLAG_IMM_SIGNED ) && (di -> ops [i ].size == 8 )) {
189189 if (di -> imm .sbyte < 0 ) {
190- chrcat_WS (str , MINUS_DISP_CHR );
191- str_int (str , - di -> imm .sbyte );
190+ chrcat_WS (& str , MINUS_DISP_CHR );
191+ tmpDisp64 = - di -> imm .sbyte ;
192+ str_int (& str , tmpDisp64 );
192193 break ;
193194 }
194195 }
195- str_int (str , di -> imm .qword );
196+ str_int (& str , di -> imm .qword );
196197 break ;
197198 case O_IMM1 :
198- str_int (str , di -> imm .ex .i1 );
199+ str_int (& str , di -> imm .ex .i1 );
199200 break ;
200201 case O_IMM2 :
201- str_int (str , di -> imm .ex .i2 );
202+ str_int (& str , di -> imm .ex .i2 );
202203 break ;
203204 case O_DISP :
204- distorm_format_size (str , di , i );
205- chrcat_WS (str , OPEN_CHR );
205+ distorm_format_size (& str , di , i );
206+ chrcat_WS (& str , OPEN_CHR );
206207 if ((SEGMENT_GET (di -> segment ) != R_NONE ) && !SEGMENT_IS_DEFAULT (di -> segment )) {
207- strcat_WSR (str , & _REGISTERS [SEGMENT_GET (di -> segment )]);
208- chrcat_WS (str , SEG_OFF_CHR );
208+ strcat_WSR (& str , & _REGISTERS [SEGMENT_GET (di -> segment )]);
209+ chrcat_WS (& str , SEG_OFF_CHR );
209210 }
210211 tmpDisp64 = di -> disp & addrMask ;
211- str_int (str , tmpDisp64 );
212- chrcat_WS (str , CLOSE_CHR );
212+ str_int (& str , tmpDisp64 );
213+ chrcat_WS (& str , CLOSE_CHR );
213214 break ;
214- case O_SMEM :
215- distorm_format_size (str , di , i );
216- chrcat_WS (str , OPEN_CHR );
215+ case O_SMEM : {
216+ int isDefault ;
217+ int segment ;
218+ distorm_format_size (& str , di , i );
219+ chrcat_WS (& str , OPEN_CHR );
217220
218221 /*
219222 * This is where we need to take special care for String instructions.
@@ -240,55 +243,60 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
240243 case I_SCAS : isDefault = FALSE; break ;
241244 }
242245 if (!isDefault && (segment != R_NONE )) {
243- strcat_WSR (str , & _REGISTERS [segment ]);
244- chrcat_WS (str , SEG_OFF_CHR );
246+ strcat_WSR (& str , & _REGISTERS [segment ]);
247+ chrcat_WS (& str , SEG_OFF_CHR );
245248 }
246249
247- strcat_WSR (str , & _REGISTERS [di -> ops [i ].index ]);
250+ strcat_WSR (& str , & _REGISTERS [di -> ops [i ].index ]);
248251
249- distorm_format_signed_disp (str , di , addrMask );
250- chrcat_WS (str , CLOSE_CHR );
251- break ;
252+ distorm_format_signed_disp (& str , di , addrMask );
253+ chrcat_WS (& str , CLOSE_CHR );
254+ } break ;
252255 case O_MEM :
253- distorm_format_size (str , di , i );
254- chrcat_WS (str , OPEN_CHR );
256+ distorm_format_size (& str , di , i );
257+ chrcat_WS (& str , OPEN_CHR );
255258 if ((SEGMENT_GET (di -> segment ) != R_NONE ) && !SEGMENT_IS_DEFAULT (di -> segment )) {
256- strcat_WSR (str , & _REGISTERS [SEGMENT_GET (di -> segment )]);
257- chrcat_WS (str , SEG_OFF_CHR );
259+ strcat_WSR (& str , & _REGISTERS [SEGMENT_GET (di -> segment )]);
260+ chrcat_WS (& str , SEG_OFF_CHR );
258261 }
259262 if (di -> base != R_NONE ) {
260- strcat_WSR (str , & _REGISTERS [di -> base ]);
261- chrcat_WS (str , PLUS_DISP_CHR );
263+ strcat_WSR (& str , & _REGISTERS [di -> base ]);
264+ chrcat_WS (& str , PLUS_DISP_CHR );
262265 }
263- strcat_WSR (str , & _REGISTERS [di -> ops [i ].index ]);
266+ strcat_WSR (& str , & _REGISTERS [di -> ops [i ].index ]);
264267 if (di -> scale != 0 ) {
265- chrcat_WS (str , '*' );
266- if (di -> scale == 2 ) chrcat_WS (str , '2' );
267- else if (di -> scale == 4 ) chrcat_WS (str , '4' );
268- else /* if (di->scale == 8) */ chrcat_WS (str , '8' );
268+ if (di -> scale == 2 ) strcat_WSN (& str , "*2" );
269+ else if (di -> scale == 4 ) strcat_WSN (& str , "*4" );
270+ else /* if (di->scale == 8) */ strcat_WSN (& str , "*8" );
269271 }
270272
271- distorm_format_signed_disp (str , di , addrMask );
272- chrcat_WS (str , CLOSE_CHR );
273+ distorm_format_signed_disp (& str , di , addrMask );
274+ chrcat_WS (& str , CLOSE_CHR );
273275 break ;
274276 case O_PC :
275277#ifdef SUPPORT_64BIT_OFFSET
276- str_int (str , (di -> imm .sqword + di -> addr + di -> size ) & addrMask );
278+ str_int (& str , (di -> imm .sqword + di -> addr + di -> size ) & addrMask );
277279#else
278280 tmpDisp64 = ((_OffsetType )di -> imm .sdword + di -> addr + di -> size ) & (uint32_t )addrMask ;
279- str_int (str , tmpDisp64 );
281+ str_int (& str , tmpDisp64 );
280282#endif
281283 break ;
282284 case O_PTR :
283- str_int (str , di -> imm .ptr .seg );
284- chrcat_WS (str , SEG_OFF_CHR );
285- str_int (str , di -> imm .ptr .off );
285+ str_int (& str , di -> imm .ptr .seg );
286+ chrcat_WS (& str , SEG_OFF_CHR );
287+ str_int (& str , di -> imm .ptr .off );
286288 break ;
287289 }
288290 }
289291
292+ /* Finalize the operands string. */
293+ strfinalize_WS (& result -> operands , str );
294+
295+
296+ /* Not used anymore.
290297 if (di->flags & FLAG_HINT_TAKEN) strcat_WSN(str, " ;TAKEN");
291298 else if (di->flags & FLAG_HINT_NOT_TAKEN) strcat_WSN(str, " ;NOT TAKEN");
299+ */
292300
293301 skipOperands :
294302 {
@@ -299,47 +307,43 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
299307
300308 mnemonic = (const _WMnemonic * )& _MNEMONICS [di -> opcode ];
301309
302- str = & result -> mnemonic ;
310+ str = ( unsigned char * ) & result -> mnemonic . p ;
303311 if (prefix ) {
304312 switch (prefix )
305313 {
306314 case FLAG_LOCK :
307- strcpy_WSN ( str , "LOCK " );
315+ strcat_WSN ( & str , "LOCK " );
308316 break ;
309317 case FLAG_REP :
310318 /* REP prefix for CMPS and SCAS is really a REPZ. */
311- if ((di -> opcode == I_CMPS ) || (di -> opcode == I_SCAS )) strcpy_WSN ( str , "REPZ " );
312- else strcpy_WSN ( str , "REP " );
319+ if ((di -> opcode == I_CMPS ) || (di -> opcode == I_SCAS )) strcat_WSN ( & str , "REPZ " );
320+ else strcat_WSN ( & str , "REP " );
313321 break ;
314322 case FLAG_REPNZ :
315- strcpy_WSN ( str , "REPNZ " );
323+ strcat_WSN ( & str , "REPNZ " );
316324 break ;
317325 }
318- }
319- else {
320- /* Init mnemonic string. */
321- str -> length = 0 ;
322- }
326+ } else result -> mnemonic .length = 0 ;
323327
324328 /*
325329 * Always copy 16 bytes from the mnemonic, we have a sentinel padding so we can read past.
326330 * This helps the compiler to remove the call to memcpy and therefore makes this copying much faster.
327331 * The longest instruction is exactly 16 chars long, but we null terminate the string below.
328332 */
329- memcpy ((int8_t * )& str -> p [ str -> length ] , mnemonic -> p , 16 );
330- str -> length += mnemonic -> length ;
333+ memcpy ((int8_t * )str , mnemonic -> p , 16 );
334+ str += mnemonic -> length ;
331335
332336 if (suffixSize ) {
333337 switch (suffixSize )
334338 {
335- case 1 : chrcat_WS (str , 'B' ); break ;
336- case 2 : chrcat_WS (str , 'W' ); break ;
337- case 4 : chrcat_WS (str , 'D' ); break ;
338- case 8 : chrcat_WS (str , 'Q' ); break ;
339+ case 1 : chrcat_WS (& str , 'B' ); break ;
340+ case 2 : chrcat_WS (& str , 'W' ); break ;
341+ case 4 : chrcat_WS (& str , 'D' ); break ;
342+ case 8 : chrcat_WS (& str , 'Q' ); break ;
339343 }
340344 }
341345
342- str -> p [ str -> length ] = 0 ;
346+ strfinalize_WS ( & result -> mnemonic , str ) ;
343347
344348 result -> offset = offset ;
345349 result -> size = size ;
@@ -354,7 +358,6 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
354358{
355359 _DecodeResult res ;
356360 _CodeInfo ci ;
357- unsigned int instsCount = 0 , i ;
358361
359362 * usedInstructionsCount = 0 ;
360363
@@ -389,8 +392,8 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
389392 if (dt == Decode16Bits ) ci .features = DF_MAXIMUM_ADDR16 ;
390393 else if (dt == Decode32Bits ) ci .features = DF_MAXIMUM_ADDR32 ;
391394
392- res = decode_internal (& ci , TRUE, (_DInst * )result , maxInstructions , & instsCount );
393- for (i = 0 ; i < instsCount ; i ++ ) {
395+ res = decode_internal (& ci , TRUE, (_DInst * )result , maxInstructions , usedInstructionsCount );
396+ for (unsigned int i = 0 , instsCount = * usedInstructionsCount ; i < instsCount ; i ++ ) {
394397 /* distorm_format is optimized and can work with same input/output buffer in-place. */
395398#ifdef SUPPORT_64BIT_OFFSET
396399 distorm_format64 (& ci , (_DInst * )& result [i ], & result [i ]);
@@ -399,7 +402,6 @@ static void distorm_format_signed_disp(_WString* str, const _DInst* di, uint64_t
399402#endif
400403 }
401404
402- * usedInstructionsCount = instsCount ;
403405 return res ;
404406}
405407
0 commit comments