Switch to length aware string

This commit is contained in:
Joel Höner 2017-12-01 20:40:56 +01:00
parent 1cd788f751
commit fa12ccb64b
6 changed files with 363 additions and 416 deletions

View File

@ -35,6 +35,7 @@
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#include <Zydis/String.h>
#ifdef __cplusplus
extern "C" {
@ -413,14 +414,13 @@ typedef struct ZydisFormatter_ ZydisFormatter;
* @c ZYDIS_FORMATTER_HOOK_POST hook-types.
*/
typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter,
const ZydisDecodedInstruction* instruction, void* userData);
ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData);
/**
* @brief Defines the @c ZydisFormatterFormatFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param str A pointer to the string buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param userData A pointer to user-defined data.
*
@ -434,14 +434,13 @@ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter,
* @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types.
*/
typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData);
ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData);
/**
* @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param str A pointer to the string buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param userData A pointer to user-defined data.
@ -471,15 +470,14 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
* hook-types.
*/
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData);
/**
* @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param str A pointer to the string buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param userData A pointer to user-defined data.
@ -494,15 +492,14 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type.
*/
typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData);
/**
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param str A pointer to the string buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param type The decorator type.
@ -520,7 +517,7 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
*/
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
/* ---------------------------------------------------------------------------------------------- */

View File

@ -164,10 +164,10 @@ enum ZydisStatusCodes
#define ZYDIS_CHECK(status) \
do \
{ \
ZydisStatus s = status; \
if (!ZYDIS_SUCCESS(s)) \
ZydisStatus status_w4587ntvmEgDG = status; \
if (!ZYDIS_SUCCESS(status_w4587ntvmEgDG)) \
{ \
return s; \
return status_w4587ntvmEgDG; \
} \
} while (0)

45
include/Zydis/String.h Normal file
View File

@ -0,0 +1,45 @@
/***************************************************************************************************
Zyan Disassembler Library (Zydis)
Original Author : Joel Höner
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#ifndef ZYDIS_STRING_H
#define ZYDIS_STRING_H
#include <Zydis/CommonTypes.h>
/* ============================================================================================== */
/* String struct */
/* ============================================================================================== */
typedef struct ZydisString_
{
char *s; // NOT always 0-terminated!
ZydisUSize length;
ZydisUSize capacity; // always -1 for 0 byte
} ZydisString;
/* ============================================================================================== */
#endif // ZYDIS_STRING_H

View File

@ -25,7 +25,6 @@
***************************************************************************************************/
#include <FormatHelper.h>
#include <LibC.h>
/* ============================================================================================== */
/* Constants */
@ -98,127 +97,16 @@ void ZydisToUpperCase(char* buffer, ZydisUSize bufferLen)
}
}
#if defined(ZYDIS_X86) || defined(ZYDIS_ARM)
ZydisStatus ZydisPrintDecU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength)
ZydisStatus ZydisPrintDecU64(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
char temp[ZYDIS_MAXCHARS_DEC_32 + 1];
char *p = &temp[ZYDIS_MAXCHARS_DEC_32];
*p = '\0';
while (value >= 100)
{
ZydisU32 const old = value;
p -= 2;
value /= 100;
ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], sizeof(ZydisU16));
}
p -= 2;
ZydisMemoryCopy(p, &decimalLookup[value * 2], sizeof(ZydisU16));
const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_32] - p;
if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1)))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisUSize offset = 0;
if (n <= paddingLength)
{
offset = paddingLength - n + 1;
ZydisMemorySet(*buffer, '0', offset);
}
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
*buffer += n + offset - (ZydisU8)(value < 10);
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintHexU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen);
if (prefix)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT));
bufferLen = bufEnd - *buffer;
}
if (bufferLen < (ZydisUSize)(paddingLength + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (!value)
{
const ZydisU8 n = (paddingLength ? paddingLength : 1);
if (bufferLen < (ZydisUSize)(n + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemorySet(*buffer, '0', n);
(*buffer)[n] = '\0';
*buffer += n;
return ZYDIS_STATUS_SUCCESS;
}
ZydisU8 n = 0;
for (ZydisI8 i = ZYDIS_MAXCHARS_HEX_32 - 1; i >= 0; --i)
{
const ZydisU8 v = (value >> i * 4) & 0x0F;
if (!n)
{
if (!v)
{
continue;
}
if (bufferLen <= (ZydisU8)(i + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (paddingLength > i)
{
n = paddingLength - i - 1;
ZydisMemorySet(*buffer, '0', n);
}
}
if (uppercase)
{
(*buffer)[n++] = "0123456789ABCDEF"[v];
} else
{
(*buffer)[n++] = "0123456789abcdef"[v];
}
}
(*buffer)[n] = '\0';
*buffer += n;
if (suffix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
}
#endif
ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
ZYDIS_ASSERT(s);
char temp[ZYDIS_MAXCHARS_DEC_64 + 1];
char *p = &temp[ZYDIS_MAXCHARS_DEC_64];
*p = '\0';
while (value >= 100)
{
ZydisU64 const old = value;
const ZydisU64 old = value;
p -= 2;
value /= 100;
ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], 2);
@ -227,7 +115,8 @@ ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value
ZydisMemoryCopy(p, &decimalLookup[value * 2], 2);
const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_64] - p;
if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1)))
if ((s->capacity - s->length < (ZydisUSize)(n + 1)) ||
(s->capacity - s->length < (ZydisUSize)(paddingLength + 1)))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
@ -236,179 +125,176 @@ ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value
if (n <= paddingLength)
{
offset = paddingLength - n + 1;
ZydisMemorySet(*buffer, '0', offset);
ZydisMemorySet(s->s + s->length, '0', offset);
}
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
*buffer += n + offset - (ZydisU8)(value < 10);
ZydisMemoryCopy(s->s + s->length + offset, &p[value < 10], n + 1);
s->length += n + offset - (ZydisU8)(value < 10);
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintHexU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen);
if (prefix)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT));
bufferLen = bufEnd - *buffer;
}
if (bufferLen < (ZydisUSize)(paddingLength + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (!value)
{
const ZydisU8 n = (paddingLength ? paddingLength : 1);
if (bufferLen < (ZydisUSize)(n + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemorySet(*buffer, '0', n);
(*buffer)[n] = '\0';
*buffer += n;
return ZYDIS_STATUS_SUCCESS;
}
ZydisU8 n = 0;
const ZydisU8 c = ((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32);
for (ZydisI8 i = c - 1; i >= 0; --i)
{
const ZydisU8 v = (value >> i * 4) & 0x0F;
if (!n)
{
if (!v)
{
continue;
}
if (bufferLen <= (ZydisU8)(i + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (paddingLength > i)
{
n = paddingLength - i - 1;
ZydisMemorySet(*buffer, '0', n);
}
}
if (uppercase)
{
(*buffer)[n++] = "0123456789ABCDEF"[v];
} else
{
(*buffer)[n++] = "0123456789abcdef"[v];
}
}
(*buffer)[n] = '\0';
*buffer += n;
if (suffix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
ZydisStatus ZydisPrintHexU64(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
ZYDIS_ASSERT(s);
if (prefix)
{
ZYDIS_CHECK(ZydisStringAppendC(s, prefix, ZYDIS_LETTER_CASE_DEFAULT));
}
char* buffer = s->s + s->length;
ZydisUSize numRemainingBytes = s->capacity - s->length;
if (numRemainingBytes < (ZydisUSize)paddingLength)
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (!value)
{
const ZydisU8 n = (paddingLength ? paddingLength : 1);
if (numRemainingBytes < (ZydisUSize)n)
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemorySet(buffer, '0', n);
s->length += n;
return ZYDIS_STATUS_SUCCESS;
}
ZydisU8 n = 0;
const ZydisU8 c = ((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32);
for (ZydisI8 i = c - 1; i >= 0; --i)
{
const ZydisU8 v = (value >> i * 4) & 0x0F;
if (!n)
{
if (!v)
{
continue;
}
if (numRemainingBytes <= (ZydisU8)(i + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (paddingLength > i)
{
n = paddingLength - i - 1;
ZydisMemorySet(buffer, '0', n);
}
}
if (uppercase)
{
buffer[n++] = "0123456789ABCDEF"[v];
} else
{
buffer[n++] = "0123456789abcdef"[v];
}
}
s->length += n;
if (suffix)
{
ZYDIS_CHECK(ZydisStringAppendC(s, suffix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* Public Functions */
/* ---------------------------------------------------------------------------------------------- */
ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text,
ZydisLetterCase letterCase)
ZydisStatus ZydisStringAppend(ZydisString* s, const ZydisString* text, ZydisLetterCase letterCase)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
ZYDIS_ASSERT(s);
ZYDIS_ASSERT(s->capacity >= s->length);
ZYDIS_ASSERT(text);
ZYDIS_ASSERT(text->capacity >= s->length);
const ZydisUSize strLen = ZydisStrLen(text);
if (strLen >= bufferLen)
if (s->length + text->length >= s->capacity)
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemoryCopy(*buffer, text, strLen + 1);
ZydisMemoryCopy(s->s + s->length, text->s, text->length);
switch (letterCase)
{
case ZYDIS_LETTER_CASE_DEFAULT:
break;
case ZYDIS_LETTER_CASE_LOWER:
ZydisToLowerCase(*buffer, strLen);
ZydisToLowerCase(s->s + s->length, text->length);
break;
case ZYDIS_LETTER_CASE_UPPER:
ZydisToUpperCase(*buffer, strLen);
ZydisToUpperCase(s->s + s->length, text->length);
break;
default:
ZYDIS_UNREACHABLE;
}
*buffer += strLen;
s->length += text->length;
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength)
ZydisStatus ZydisPrintDecU(ZydisString *s, ZydisU64 value, ZydisU8 paddingLength)
{
#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64)
return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength);
return ZydisPrintDecU64(s, value, paddingLength);
#else
if (value & 0xFFFFFFFF00000000)
{
return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength);
return ZydisPrintDecU64(s, value, paddingLength);
} else
{
return ZydisPrintDecU32(buffer, bufferLen, (ZydisU32)value, paddingLength);
return ZydisPrintDecU32(s, (ZydisU32)value, paddingLength);
}
#endif
}
ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength)
ZydisStatus ZydisPrintDecS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength)
{
if (value < 0)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
return ZydisPrintDecU(buffer, bufferLen - 1, -value, paddingLength);
ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT));
return ZydisPrintDecU(s, -value, paddingLength);
}
return ZydisPrintDecU(buffer, bufferLen, value, paddingLength);
return ZydisPrintDecU(s, value, paddingLength);
}
ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength,
ZydisStatus ZydisPrintHexU(ZydisString *s, ZydisU64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64)
return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
return ZydisPrintHexU64(s, value, paddingLength, uppercase, prefix, suffix);
#else
if (value & 0xFFFFFFFF00000000)
{
return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
return ZydisPrintHexU64(s, value, paddingLength, uppercase, prefix, suffix);
} else
{
return ZydisPrintHexU32(buffer, bufferLen, (ZydisU32)value, paddingLength, uppercase,
prefix, suffix);
return ZydisPrintHexU32(s, (ZydisU32)value, paddingLength, uppercase, prefix, suffix);
}
#endif
}
ZydisStatus ZydisPrintHexS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength,
ZydisStatus ZydisPrintHexS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
if (value < 0)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT));
if (prefix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, prefix, ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(s, prefix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZydisPrintHexU(buffer, bufEnd - *buffer, -value, paddingLength, uppercase,
ZYDIS_NULL, suffix);
return ZydisPrintHexU(s, -value, paddingLength, uppercase, ZYDIS_NULL, suffix);
}
return ZydisPrintHexU(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
return ZydisPrintHexU(s, value, paddingLength, uppercase, prefix, suffix);
}
/* ---------------------------------------------------------------------------------------------- */

View File

@ -29,6 +29,8 @@
#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#include <Zydis/String.h>
#include <LibC.h>
#ifdef __cplusplus
extern "C" {
@ -77,22 +79,44 @@ enum ZydisLetterCases
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Appends the given @c text to the @c buffer.
* @brief Appends the @c ZydisString to another @c ZydisString.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param buffer The string to append to.
* @param text The string to append.
* @param letterCase The desired letter-case.
*
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
* sufficient to append the given @c text.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisStringAppend(
ZydisString* s, const ZydisString* text, ZydisLetterCase letterCase);
/**
* @brief Appends the given C string to the @c ZydisString.
*
* @param s The string to append to.
* @param text The text to append.
* @param letterCase The desired letter-case.
*
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
* sufficient to append the given @c text.
*
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text,
ZydisLetterCase letterCase);
ZYDIS_INLINE ZydisStatus ZydisStringAppendC(
ZydisString* s, const char* text, ZydisLetterCase letterCase)
{
ZYDIS_ASSERT(text);
ZydisUSize len = ZydisStrLen(text);
ZydisString zyStr = {
.s = (char*)text,
.length = len,
.capacity = len
};
return ZydisStringAppend(s, &zyStr, letterCase);
}
/* ---------------------------------------------------------------------------------------------- */
/* Decimal values */
@ -100,10 +124,9 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, c
/**
* @brief Formats the given unsigned ordinal @c value to its decimal text-representation and
* appends it to the @c buffer.
* appends it to @c s.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param s A pointer to the string.
* @param value The value.
* @param paddingLength Padds the converted value with leading zeros, if the number of chars is
* less than the @c paddingLength.
@ -115,15 +138,13 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, c
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, ZydisU64 value,
ZydisU8 paddingLength);
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength);
/**
* @brief Formats the given signed ordinal @c value to its decimal text-representation and
* appends it to the @c buffer.
* appends it to @c s.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param s A pointer to the string.
* @param value The value.
* @param paddingLength Padds the converted value with leading zeros, if the number of chars is
* less than the @c paddingLength (the sign char is ignored).
@ -135,7 +156,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen,
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, ZydisI64 value,
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(ZydisString* s, ZydisI64 value,
ZydisU8 paddingLength);
/* ---------------------------------------------------------------------------------------------- */
@ -146,8 +167,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen,
* @brief Formats the given unsigned ordinal @c value to its hexadecimal text-representation and
* appends it to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param s A pointer to the string.
* @param value The value.
* @param paddingLength Padds the converted value with leading zeros, if the number of chars is
* less than the @c paddingLength.
@ -163,15 +183,14 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen,
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, ZydisU64 value,
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(ZydisString* s, ZydisU64 value,
ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix);
/**
* @brief Formats the given signed ordinal @c value to its hexadecimal text-representation and
* appends it to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param s A pointer to the string.
* @param value The value.
* @param paddingLength Padds the converted value with leading zeros, if the number of chars is
* less than the @c paddingLength (the sign char is ignored).
@ -187,7 +206,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen,
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(char** buffer, ZydisUSize bufferLen, ZydisI64 value,
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(ZydisString* s, ZydisI64 value,
ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix);
/* ---------------------------------------------------------------------------------------------- */

View File

@ -39,72 +39,70 @@
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
if (!formatter || !buffer || !instruction)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK)
{
return ZydisPrintStr(buffer, bufferLen, "lock ", formatter->letterCase);
return ZydisStringAppendC(buffer, "lock ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP)
{
return ZydisPrintStr(buffer, bufferLen, "rep ", formatter->letterCase);
return ZydisStringAppendC(buffer, "rep ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE)
{
return ZydisPrintStr(buffer, bufferLen, "repe ", formatter->letterCase);
return ZydisStringAppendC(buffer, "repe ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE)
{
return ZydisPrintStr(buffer, bufferLen, "repne ", formatter->letterCase);
return ZydisStringAppendC(buffer, "repne ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND)
{
return ZydisPrintStr(buffer, bufferLen, "bnd ", formatter->letterCase);
return ZydisStringAppendC(buffer, "bnd ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE)
{
return ZydisPrintStr(buffer, bufferLen, "xacquire ", formatter->letterCase);
return ZydisStringAppendC(buffer, "xacquire ", formatter->letterCase);
}
if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
{
return ZydisPrintStr(buffer, bufferLen, "xrelease ", formatter->letterCase);
return ZydisStringAppendC(buffer, "xrelease ", formatter->letterCase);
}
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
if (!formatter || !buffer || !instruction)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
const char* mnemonic = ZydisMnemonicGetString(instruction->mnemonic);
if (!mnemonic)
{
mnemonic = "invalid";
}
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, mnemonic, formatter->letterCase));
ZYDIS_CHECK(ZydisStringAppendC(buffer, mnemonic, formatter->letterCase));
if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH)
{
return ZydisPrintStr(buffer, bufEnd - *buffer, " far", formatter->letterCase);
return ZydisStringAppendC(buffer, " far", formatter->letterCase);
}
return ZYDIS_STATUS_SUCCESS;
@ -113,12 +111,12 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -133,21 +131,20 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
{
reg = "invalid";
}
return ZydisPrintStr(buffer, bufferLen, reg, formatter->letterCase);
return ZydisStringAppendC(buffer, reg, formatter->letterCase);
}
static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "[", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(buffer, "[", ZYDIS_LETTER_CASE_DEFAULT));
if (operand->mem.disp.hasDisplacement && (
(operand->mem.base == ZYDIS_REGISTER_NONE) ||
@ -161,14 +158,14 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
{
ZydisU64 address;
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer,
instruction, operand, address, userData));
ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, instruction, operand,
address, userData));
} else
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer,
ZydisRegisterGetString(operand->mem.base), formatter->letterCase));
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
instruction, operand, userData));
ZYDIS_CHECK(ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.base),
formatter->letterCase));
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, instruction, operand,
userData));
}
} else
{
@ -180,7 +177,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase));
ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase));
}
if ((operand->mem.index != ZYDIS_REGISTER_NONE) &&
(operand->mem.type != ZYDIS_MEMOP_TYPE_MIB))
@ -193,47 +190,46 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
if (operand->mem.base != ZYDIS_REGISTER_NONE)
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, "+", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT));
}
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase));
ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase));
if (operand->mem.scale)
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, "*", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisPrintDecU(buffer, bufEnd - *buffer, operand->mem.scale, 0));
ZydisStringAppendC(buffer, "*", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisPrintDecU(buffer, operand->mem.scale, 0));
}
}
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer,
instruction, operand, userData));
}
return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT);
return ZydisStringAppendC(buffer, "]", ZYDIS_LETTER_CASE_DEFAULT);
}
static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintHexU(buffer, bufEnd - *buffer, operand->ptr.segment, 4,
ZYDIS_CHECK(ZydisPrintHexU(buffer, operand->ptr.segment, 4,
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix));
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT));
return ZydisPrintHexU(buffer, bufEnd - *buffer, operand->ptr.offset, 8,
ZYDIS_CHECK(ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT));
return ZydisPrintHexU(buffer, operand->ptr.offset, 8,
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
}
static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -248,7 +244,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
{
ZydisU64 address;
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand,
return formatter->funcPrintAddress(formatter, buffer, instruction, operand,
address, userData);
}
case ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED:
@ -262,29 +258,29 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
if (printSignedHEX)
{
return ZydisPrintHexS(buffer, bufferLen, (ZydisI32)operand->imm.value.s,
return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s,
formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
}
return ZydisPrintHexU(buffer, bufferLen, operand->imm.value.u,
return ZydisPrintHexU(buffer, operand->imm.value.u,
formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
}
// The immediate operand contains an actual ordinal value
return formatter->funcPrintImmediate(
formatter, buffer, bufferLen, instruction, operand, userData);
formatter, buffer, instruction, operand, userData);
}
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -292,13 +288,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
switch (instruction->stackWidth)
{
case 16:
return ZydisPrintHexU(buffer, bufferLen, (ZydisU16)address, 4,
return ZydisPrintHexU(buffer, (ZydisU16)address, 4,
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
case 32:
return ZydisPrintHexU(buffer, bufferLen, (ZydisU32)address, 8,
return ZydisPrintHexU(buffer, (ZydisU32)address, 8,
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
case 64:
return ZydisPrintHexU(buffer, bufferLen, address, 16,
return ZydisPrintHexU(buffer, address, 16,
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -306,12 +302,12 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
}
static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -326,17 +322,16 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
{
return ZydisPrintHexS(buffer, bufferLen, operand->mem.disp.value,
return ZydisPrintHexS(buffer, operand->mem.disp.value,
formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
}
const char* bufEnd = *buffer + bufferLen;
if ((operand->mem.base != ZYDIS_REGISTER_NONE) ||
(operand->mem.index != ZYDIS_REGISTER_NONE))
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "+", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT));
}
return ZydisPrintHexU(buffer, bufEnd - *buffer, (ZydisU64)operand->mem.disp.value,
return ZydisPrintHexU(buffer, (ZydisU64)operand->mem.disp.value,
formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
}
@ -344,12 +339,12 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
}
static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -365,19 +360,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
switch (operand->size)
{
case 8:
return ZydisPrintHexS(buffer, bufferLen, (ZydisI8)operand->imm.value.s,
return ZydisPrintHexS(buffer, (ZydisI8)operand->imm.value.s,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 16:
return ZydisPrintHexS(buffer, bufferLen, (ZydisI16)operand->imm.value.s,
return ZydisPrintHexS(buffer, (ZydisI16)operand->imm.value.s,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 32:
return ZydisPrintHexS(buffer, bufferLen, (ZydisI32)operand->imm.value.s,
return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 64:
return ZydisPrintHexS(buffer, bufferLen, operand->imm.value.s,
return ZydisPrintHexS(buffer, operand->imm.value.s,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
default:
@ -387,19 +382,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
switch (instruction->operandWidth)
{
case 8:
return ZydisPrintHexU(buffer, bufferLen, (ZydisU8)operand->imm.value.u,
return ZydisPrintHexU(buffer, (ZydisU8)operand->imm.value.u,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 16:
return ZydisPrintHexU(buffer, bufferLen, (ZydisU16)operand->imm.value.u,
return ZydisPrintHexU(buffer, (ZydisU16)operand->imm.value.u,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 32:
return ZydisPrintHexU(buffer, bufferLen, (ZydisU32)operand->imm.value.u,
return ZydisPrintHexU(buffer, (ZydisU32)operand->imm.value.u,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
case 64:
return ZydisPrintHexU(buffer, bufferLen, operand->imm.value.u,
return ZydisPrintHexU(buffer, operand->imm.value.u,
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
formatter->hexSuffix);
default:
@ -410,12 +405,12 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
/* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -510,24 +505,23 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
if (str)
{
return ZydisPrintStr(buffer, bufferLen, str, formatter->letterCase);
return ZydisStringAppendC(buffer, str, formatter->letterCase);
}
}
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
switch (operand->mem.segment)
{
case ZYDIS_REGISTER_ES:
@ -535,17 +529,17 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
case ZYDIS_REGISTER_FS:
case ZYDIS_REGISTER_GS:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer,
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
formatter->letterCase));
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
case ZYDIS_REGISTER_SS:
if ((formatter->forceSegments) ||
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer,
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
formatter->letterCase));
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
}
break;
case ZYDIS_REGISTER_DS:
@ -553,9 +547,9 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer,
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
formatter->letterCase));
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
}
break;
default:
@ -565,17 +559,16 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
}
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData)
{
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
if (!formatter || !buffer || !instruction || !operand)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
switch (type)
{
case ZYDIS_DECORATOR_TYPE_MASK:
@ -587,13 +580,13 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " {", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase));
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "}", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(buffer, " {", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase));
ZYDIS_CHECK(ZydisStringAppendC(buffer, "}", ZYDIS_LETTER_CASE_DEFAULT));
if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO)
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT));
}
}
break;
@ -607,27 +600,27 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
break;
case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_BROADCAST_MODE_4_TO_16:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -642,20 +635,20 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisPrintStr(
buffer, bufEnd - *buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(
buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisPrintStr(
buffer, bufEnd - *buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(
buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisPrintStr(
buffer, bufEnd - *buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(
buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisPrintStr(
buffer, bufEnd - *buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(
buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -668,19 +661,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -691,7 +684,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
if (instruction->avx.hasSAE && !instruction->avx.rounding.mode)
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT));
}
break;
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
@ -703,31 +696,31 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
break;
case ZYDIS_SWIZZLE_MODE_CDAB:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_BADC:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -740,23 +733,23 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
break;
case ZYDIS_CONVERSION_MODE_FLOAT16:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_CONVERSION_MODE_SINT8:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_CONVERSION_MODE_UINT8:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_CONVERSION_MODE_SINT16:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT));
break;
case ZYDIS_CONVERSION_MODE_UINT16:
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -766,7 +759,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(
ZydisPrintStr(buffer, bufEnd - *buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT));
ZydisStringAppendC(buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT));
}
break;
default:
@ -777,20 +770,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
}
static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
if (!formatter || !buffer || !instruction)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(
formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction, userData));
formatter->funcPrintPrefixes(formatter, buffer, instruction, userData));
ZYDIS_CHECK(
formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction, userData));
formatter->funcPrintMnemonic(formatter, buffer, instruction, userData));
char* bufRestore = *buffer;
ZydisUSize lenRestore = buffer->length;
for (ZydisU8 i = 0; i < instruction->operandCount; ++i)
{
if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
@ -800,52 +792,51 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if (i == 0)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
ZYDIS_CHECK(ZydisStringAppendC(buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
} else
{
bufRestore = *buffer;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
lenRestore = buffer->length;
ZYDIS_CHECK(ZydisStringAppendC(buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
}
const char* bufPreOperand = *buffer;
ZydisUSize bufPreOperandLen = buffer->length;
switch (instruction->operands[i].type)
{
case ZYDIS_OPERAND_TYPE_REGISTER:
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer,
instruction, &instruction->operands[i], userData));
break;
case ZYDIS_OPERAND_TYPE_MEMORY:
{
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer,
instruction, &instruction->operands[i], userData));
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer,
instruction, &instruction->operands[i], userData));
const char* bufTemp = *buffer;
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer,
ZydisUSize lenTemp = buffer->length;
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer,
instruction, &instruction->operands[i], userData));
if (bufTemp == *buffer)
if (lenTemp == buffer->length)
{
*buffer = (char*)bufPreOperand;
buffer->length = bufPreOperandLen;
}
break;
}
case ZYDIS_OPERAND_TYPE_POINTER:
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer,
instruction, &instruction->operands[i], userData));
break;
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer,
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer,
instruction, &instruction->operands[i], userData));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if (bufPreOperand == *buffer)
if (lenRestore == buffer->length)
{
// Omit whole operand, if the buffer did not change during the formatting-callback
*buffer = bufRestore;
*buffer[0] = 0;
buffer->length = lenRestore;
} else
{
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
@ -855,21 +846,21 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
(instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK))
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK, userData));
}
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST, userData));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_CONVERSION, userData));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData));
}
} else
@ -880,14 +871,14 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SWIZZLE, userData));
}
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, userData));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SAE, userData));
}
}
@ -1156,21 +1147,30 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter,
const ZydisDecodedInstruction* instruction, char* buffer, ZydisUSize bufferLen, void* userData)
{
if (!formatter || !instruction || !buffer || (bufferLen == 0))
if (!formatter || !instruction || !buffer || !bufferLen)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZydisString str = {
.s = buffer,
.length = 0,
.capacity = bufferLen - 1
};
if (formatter->funcPre)
{
ZYDIS_CHECK(formatter->funcPre(formatter, instruction, userData));
ZYDIS_CHECK(formatter->funcPre(formatter, &str, instruction, userData));
}
ZYDIS_CHECK(
formatter->funcFormatInstruction(formatter, &buffer, bufferLen, instruction, userData));
ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &str, instruction, userData));
if (formatter->funcPost)
{
return formatter->funcPost(formatter, instruction, userData);
ZYDIS_CHECK(formatter->funcPost(formatter, &str, instruction, userData));
}
str.s[str.length] = 0;
return ZYDIS_STATUS_SUCCESS;
}