parent
225ec192c5
commit
33d3ded40b
@ -0,0 +1,3 @@
|
||||
[submodule "dependencies/cli-parser"]
|
||||
path = dependencies/cli-parser
|
||||
url = https://githacks.org/_xeroxz/cli-parser.git
|
@ -0,0 +1 @@
|
||||
Subproject commit 1aedaf8bb7f383f54b7cd498767611535526da85
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_assembler.h
|
||||
* Structures and functions declarations related to one-line FCML assembler.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ASSEMBLER_H_
|
||||
#define FCML_ASSEMBLER_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_common.h"
|
||||
#include "fcml_dialect.h"
|
||||
#include "fcml_optimizers.h"
|
||||
#include "fcml_choosers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Abstract assembler representation. */
|
||||
typedef struct fcml_st_assembler fcml_st_assembler;
|
||||
|
||||
/**
|
||||
* Assembler runtime configuration.
|
||||
*/
|
||||
typedef struct fcml_st_assembler_conf {
|
||||
/** Set to true in order to force assembler to increment IP address by
|
||||
* length of the assembled instruction. */
|
||||
fcml_bool increment_ip;
|
||||
/** True if optional error and warning messages should be collected
|
||||
* during processing. */
|
||||
fcml_bool enable_error_messages;
|
||||
/** If there are SIB and "ModR/M only" encodings available, choose
|
||||
* the SIB based one. */
|
||||
fcml_bool choose_sib_encoding;
|
||||
/** If memory address can be encoded as relative or absolute value choose
|
||||
* the absolute addressing. It works in 64 bit mode only. */
|
||||
fcml_bool choose_abs_encoding;
|
||||
/** Sometimes REX prefix is useless so it is just omitted in the final
|
||||
* machine code. By setting this flag to true you can force this prefix
|
||||
to be added anyway. */
|
||||
fcml_bool force_rex_prefix;
|
||||
/** Every 2 byte VEX/XOP prefix can be encoded using three byte form.
|
||||
* Setting this flag to true forces it. */
|
||||
fcml_bool force_three_byte_VEX;
|
||||
/** Optimizer implementation that should be used by assembler. Setting it
|
||||
* to NULL causes assembler to use default one. */
|
||||
fcml_fnp_asm_optimizer optimizer;
|
||||
/** This field is passed to the chosen optimizer. It can be used to
|
||||
* configure its behavior. */
|
||||
fcml_uint16_t optimizer_flags;
|
||||
/** instruction chooser implementation that should be used by assembler
|
||||
* to choose most appropriate instruction encoding. Setting this value to
|
||||
* NULL cause assembler to use default instruction chooser. */
|
||||
fcml_fnp_asm_instruction_chooser chooser;
|
||||
} fcml_st_assembler_conf;
|
||||
|
||||
/**
|
||||
* Encoded instruction.
|
||||
* Every instruction might be encoded to more than one binary form.
|
||||
* This chain holds all forms assembler was able to assemble instruction to.
|
||||
*/
|
||||
typedef struct fcml_st_assembled_instruction {
|
||||
/** Next assembled instruction in the chain. */
|
||||
struct fcml_st_assembled_instruction *next;
|
||||
/** Warning messages related to assembled instruction.*/
|
||||
fcml_st_ceh_error_container warnings;
|
||||
/** Instruction machine code.*/
|
||||
fcml_uint8_t *code;
|
||||
/** Instruction code length in bytes.*/
|
||||
fcml_usize code_length;
|
||||
#ifdef FCML_DEBUG
|
||||
fcml_uint8_t __def_index;
|
||||
#endif
|
||||
} fcml_st_assembled_instruction;
|
||||
|
||||
/** Assembler result. */
|
||||
typedef struct fcml_st_assembler_result {
|
||||
/** Error and warning messages from assembler.*/
|
||||
fcml_st_ceh_error_container errors;
|
||||
/** Chain of assembled instructions. */
|
||||
fcml_st_assembled_instruction *instructions;
|
||||
/** Instruction chosen by used instruction chooser; otherwise NULL.*/
|
||||
fcml_st_assembled_instruction *chosen_instruction;
|
||||
/** Number of encoded instruction forms. */
|
||||
fcml_usize number_of_instructions;
|
||||
} fcml_st_assembler_result;
|
||||
|
||||
/** Assembler runtime context. */
|
||||
typedef struct fcml_st_assembler_context {
|
||||
/** Assembler instance that should be used to assemble instructions. */
|
||||
fcml_st_assembler *assembler;
|
||||
/** Assembler behavior can be configured here.*/
|
||||
fcml_st_assembler_conf configuration;
|
||||
/** Instruction entry point configuration. */
|
||||
fcml_st_entry_point entry_point;
|
||||
} fcml_st_assembler_context;
|
||||
|
||||
/**
|
||||
* Initializes assembler for given dialect.
|
||||
* Initializes assembler instance for given dialect (Intel, AT&T). Assembler
|
||||
* initialized in such a way is dialect dependent and supports GIM with the
|
||||
* syntax supported by it. Every assembler instance has to be freed using
|
||||
* fcml_fn_assembler_free() function as soon as it is not needed anymore.
|
||||
*
|
||||
* @param dialect Dialect instance.
|
||||
* @param[out] assembler Initialized assembler instance.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
* @see fcml_fn_assembler_free
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_assembler_init(
|
||||
const fcml_st_dialect *dialect, fcml_st_assembler **assembler);
|
||||
|
||||
/**
|
||||
* Assembles one instruction encoded in the generic instruction model.
|
||||
* Instruction is proceeded using configuration and assembler provided
|
||||
* in given fcml_st_assembler_context instance. Assembled code as well
|
||||
* as potential errors or warnings are accessible via provided reusable
|
||||
* result holder instance. Result holder has to be allocated by the
|
||||
* user and appropriately prepared using fcml_fn_assembler_result_prepare()
|
||||
* function. As long as the instruction context and the result holder
|
||||
* are not shared across multiple function calls assembling process is
|
||||
* thread safe.
|
||||
*
|
||||
* @param context Assembler context (Assembler, Entry Point, Configuration).
|
||||
* @param instruction Instruction encoded as generic instruction model
|
||||
* (Dialect dependent).
|
||||
* @param result Result holder (Remember to prepare it appropriately).
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
* @see fcml_fn_assembler_result_prepare fcml_fn_assembler_init
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_assemble(
|
||||
fcml_st_assembler_context *context,
|
||||
const fcml_st_instruction *instruction,
|
||||
fcml_st_assembler_result *result);
|
||||
|
||||
/**
|
||||
* Prepares reusable result holder for assembler.
|
||||
* Every instance of fcml_st_assembler_result structure is reusable from
|
||||
* the assembler's point of view, so it has to be prepared in the right way
|
||||
* in order to allow assembler to reuse it correctly. It is up to the library
|
||||
* user to allocate space for the holder itself. This function is only
|
||||
* responsible for cleaning the structure correctly and preparing it for the
|
||||
* first assembling process. Notice that assembler has to clean the result
|
||||
* holder at the beginning so you can not pass an uninitialized memory block
|
||||
* because it can even cause a crash due to illegal memory access.
|
||||
*
|
||||
* @param result Result holder instance to be prepared.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_assembler_result_prepare(
|
||||
fcml_st_assembler_result *result);
|
||||
|
||||
/**
|
||||
* Cleans result holder.
|
||||
* Frees all memory blocks allocated by the assembler and held inside the
|
||||
* result holder (Instructions, errors etc.). Notice that result holder itself
|
||||
* is not freed and can be even safety reused after call to this function. In
|
||||
* fact this function is also called internally by the assembler in order to
|
||||
* clean result holder before reusing it.
|
||||
* @param result Result holder to clean.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_assembler_result_free(
|
||||
fcml_st_assembler_result *result);
|
||||
|
||||
/**
|
||||
* Frees assembled instruction.
|
||||
* Take into account that it does not free whole chain recursively but only
|
||||
* the one instruction you have provided.
|
||||
* @param instruction Instruction to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_assembler_instruction_free(
|
||||
fcml_st_assembled_instruction *instruction);
|
||||
|
||||
/**
|
||||
* Detaches given instruction from the instructions chain.
|
||||
* Removes given assembled instruction from the provided chain in order
|
||||
* to prevent premature freeing of memory while assembler cleans result holder
|
||||
* reusing it. Detached instructions are not automatically deallocated by
|
||||
* fcml_fn_assemble() or fcml_fn_assembler_result_free() functions, so
|
||||
* it is up to you to free it using fcml_fn_assembler_instruction_free()
|
||||
* function when it is not needed anymore. Function may be useful
|
||||
* when you need to store assembled instructions across multiple calls
|
||||
* to the assembler if you reuse the same result holder. If there is only one
|
||||
* instruction in the chain its pointer will be set to NULL after detaching it.
|
||||
* @param chain Pointer to the instructions chain pointer.
|
||||
* @param instruction Instruction to be detached from the chain.
|
||||
*
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_assembler_instruction_detach(
|
||||
fcml_st_assembled_instruction **chain,
|
||||
fcml_st_assembled_instruction *instruction);
|
||||
|
||||
/**
|
||||
* Frees assembler instance.
|
||||
* Every assembler instance manages some resources internally and as such it has
|
||||
* to be deallocated as soon as it is not needed anymore.
|
||||
* @param assembler Assembler to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_assembler_free(fcml_st_assembler *assembler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_ASSEMBLER_H_ */
|
@ -0,0 +1,946 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_assembler.hpp
|
||||
* C++ wrapper for FCML assembler.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ASSEMBLER_HPP_
|
||||
#define FCML_ASSEMBLER_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
#include "fcml_assembler.h"
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
#include "fcml_errors.hpp"
|
||||
#include "fcml_dialect.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* Assembling failed.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class AssemblingFailedException: public ErrorContainerAwareException {
|
||||
public:
|
||||
AssemblingFailedException(const fcml_cstring msg,
|
||||
ErrorContainer errorContainer = ErrorContainer(),
|
||||
fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR) :
|
||||
ErrorContainerAwareException(msg, errorContainer, error) {
|
||||
}
|
||||
};
|
||||
|
||||
/** Describes an assembled instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class AssembledInstruction {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an assembled instruction basing on given code buffer and errors.
|
||||
*
|
||||
* @param buffer Pointer to the machine code buffer.
|
||||
* @param len Number of machine code bytes.
|
||||
* @param errorContainer Potential warnings related to the
|
||||
* assembled instruction.
|
||||
* @since 1.1.0
|
||||
*
|
||||
*/
|
||||
AssembledInstruction(const fcml_uint8_t *buffer, fcml_usize len,
|
||||
const ErrorContainer &errorContainer) {
|
||||
set(buffer, len, errorContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssembledInstruction(const AssembledInstruction &cpy) {
|
||||
set(cpy._code, cpy._codeLength, cpy._warningContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies one instruction into another.
|
||||
*
|
||||
* @param cpy The source instruction.
|
||||
* @return A reference to the destination instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssembledInstruction& operator=(const AssembledInstruction &cpy) {
|
||||
if (&cpy != this) {
|
||||
if (this->_code) {
|
||||
delete[] this->_code;
|
||||
}
|
||||
set(cpy._code, cpy._codeLength, cpy._warningContainer);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~AssembledInstruction() {
|
||||
if (_code) {
|
||||
delete[] _code;
|
||||
_code = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets pointer to machine code buffer.
|
||||
*
|
||||
* @return Pointer to machine code buffer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const fcml_uint8_t* getCode() const {
|
||||
return _code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of bytes in the buffer.
|
||||
*
|
||||
* @return Number of bytes in the buffer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_usize getCodeLength() const {
|
||||
return _codeLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference to the errors container.
|
||||
*
|
||||
* @return A reference to the errors container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorContainer& getWarningContainer() const {
|
||||
return _warningContainer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Fills the assembled instruction with new data.
|
||||
*
|
||||
* @param buffer The code buffer.
|
||||
* @param len The code buffer lenght.
|
||||
* @param warnings The warnings container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void set(const fcml_uint8_t *buffer, fcml_usize len,
|
||||
const ErrorContainer warnigns) {
|
||||
_warningContainer = warnigns;
|
||||
if (len > 0) {
|
||||
_code = new fcml_uint8_t[len];
|
||||
for (fcml_usize i = 0; i < len; i++) {
|
||||
_code[i] = buffer[i];
|
||||
}
|
||||
} else {
|
||||
_code = NULL;
|
||||
}
|
||||
_codeLength = len;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Warnings related to this instruction. */
|
||||
ErrorContainer _warningContainer;
|
||||
|
||||
/** Pointer to the instruction machine code. */
|
||||
fcml_uint8_t *_code;
|
||||
|
||||
/** Number of machine code bytes in the array above. */
|
||||
fcml_usize _codeLength;
|
||||
|
||||
};
|
||||
|
||||
class Assembler;
|
||||
|
||||
/** Assembler result. */
|
||||
class AssemblerResult {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerResult() :
|
||||
_chosenInstructionIndex(-1) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets instruction chosen by the assembler as the preferred one.
|
||||
*
|
||||
* @return Preferred instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const AssembledInstruction* getChosenInstruction() const {
|
||||
if (_chosenInstructionIndex == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return &(_assembledInstructions[_chosenInstructionIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets errors container.
|
||||
*
|
||||
* @return Errors container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorContainer& getErrorContainer() const {
|
||||
return _errorContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of instructions alternatives available in the result.
|
||||
*
|
||||
* @return Number of available instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_usize getSize() const {
|
||||
return static_cast<fcml_usize>(_assembledInstructions.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets pointer to the chosen instruction.
|
||||
*
|
||||
* @return Pointer to the chosen instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
operator const AssembledInstruction*() const {
|
||||
if (_chosenInstructionIndex == -1) {
|
||||
return NULL;
|
||||
}
|
||||
return &(_assembledInstructions[_chosenInstructionIndex]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an assembled instruction reference by its index.
|
||||
*
|
||||
* @return The assembled instruction for given index.
|
||||
* @throw BadArgumentException Array index out of bound.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const AssembledInstruction& operator[](fcml_usize index) const {
|
||||
if (index > _assembledInstructions.size()) {
|
||||
throw BadArgumentException(FCML_TEXT("Array index out of bound."),
|
||||
FCML_CEH_GEC_VALUE_OUT_OF_RANGE);
|
||||
}
|
||||
return _assembledInstructions[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies machine code of the chosen instruction to the output stream.
|
||||
*
|
||||
* @param[out] out Output stream.
|
||||
* @param result Assembler result.
|
||||
* @return Output stream from the parameter.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
friend std::basic_ostream<fcml_uint8_t>& operator<<(
|
||||
std::basic_ostream<fcml_uint8_t> &out,
|
||||
const AssemblerResult &result) {
|
||||
const AssembledInstruction *assembled = result.getChosenInstruction();
|
||||
if (assembled) {
|
||||
// If chosen instruction is not available, do not
|
||||
// stream anything. It's not so common, because
|
||||
// instructions choosers are obliged to chose something.
|
||||
if (assembled->getCode() && assembled->getCodeLength() > 0) {
|
||||
out.write(assembled->getCode(), assembled->getCodeLength());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears assembler result by removing all assembled instructions,
|
||||
* errors and reseting the chosen instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void clear() {
|
||||
_errorContainer.clean();
|
||||
_assembledInstructions.clear();
|
||||
_chosenInstructionIndex = -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend Assembler;
|
||||
|
||||
void setErrorContainer(const ErrorContainer &errorContainer) {
|
||||
_errorContainer = errorContainer;
|
||||
}
|
||||
|
||||
std::vector<AssembledInstruction>& getAssembledInstructions() {
|
||||
return _assembledInstructions;
|
||||
}
|
||||
|
||||
void setChoosenInstructionIndex(fcml_int index) {
|
||||
_chosenInstructionIndex = index;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Assembling errors. */
|
||||
ErrorContainer _errorContainer;
|
||||
/** All assembled instructions are going here. */
|
||||
std::vector<AssembledInstruction> _assembledInstructions;
|
||||
/** Index for the chosen instruction. */
|
||||
fcml_int _chosenInstructionIndex;
|
||||
|
||||
};
|
||||
|
||||
/** Assembler configuration.
|
||||
* For more information about the flags, see fcml_st_assembler_conf
|
||||
* structure documentation.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class AssemblerConf {
|
||||
public:
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerConf() :
|
||||
_throwExceptionOnError(true),
|
||||
_incrementIp(true),
|
||||
_enableErrorMessages(true),
|
||||
_chooseSibEncoding(false),
|
||||
_chooseAbsEncoding(false),
|
||||
_forceRexPrefix(false),
|
||||
_forceThreeByteVEX(false),
|
||||
_noBranchPrediction(false),
|
||||
_optimizer(NULL),
|
||||
_optimizerFlags(0),
|
||||
_chooser(NULL) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isChooseAbsEncoding() const {
|
||||
return _chooseAbsEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setChooseAbsEncoding(bool chooseAbsEncoding) {
|
||||
_chooseAbsEncoding = chooseAbsEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_fnp_asm_instruction_chooser getChooser() const {
|
||||
return _chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setChooser(fcml_fnp_asm_instruction_chooser chooser) {
|
||||
_chooser = chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isChooseSibEncoding() const {
|
||||
return _chooseSibEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setChooseSibEncoding(bool chooseSibEncoding) {
|
||||
_chooseSibEncoding = chooseSibEncoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isEnableErrorMessages() const {
|
||||
return _enableErrorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setEnableErrorMessages(bool enableErrorMessages) {
|
||||
_enableErrorMessages = enableErrorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isForceRexPrefix() const {
|
||||
return _forceRexPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setForceRexPrefix(bool forceRexPrefix) {
|
||||
_forceRexPrefix = forceRexPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isForceThreeByteVex() const {
|
||||
return _forceThreeByteVEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setForceThreeByteVex(bool forceThreeByteVex) {
|
||||
_forceThreeByteVEX = forceThreeByteVex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isIncrementIp() const {
|
||||
return _incrementIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setIncrementIp(bool incrementIp) {
|
||||
_incrementIp = incrementIp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_fnp_asm_optimizer getOptimizer() const {
|
||||
return _optimizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOptimizer(fcml_fnp_asm_optimizer optimizer) {
|
||||
_optimizer = optimizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_uint16_t getOptimizerFlags() const {
|
||||
return _optimizerFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOptimizerFlags(fcml_uint16_t optimizerFlags) {
|
||||
_optimizerFlags = optimizerFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if exception should be thrown when assembling fails.
|
||||
*
|
||||
* @return True if exception is the preferred way of error handling
|
||||
* in case of failure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isThrowExceptionOnError() const {
|
||||
return _throwExceptionOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the way how the error handling is done.
|
||||
*
|
||||
* @param throwExceptionOnError True if exception should be thrown
|
||||
* in case of failure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setThrowExceptionOnError(bool throwExceptionOnError) {
|
||||
_throwExceptionOnError = throwExceptionOnError;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _throwExceptionOnError;
|
||||
bool _incrementIp;
|
||||
bool _enableErrorMessages;
|
||||
bool _chooseSibEncoding;
|
||||
bool _chooseAbsEncoding;
|
||||
bool _forceRexPrefix;
|
||||
bool _forceThreeByteVEX;
|
||||
bool _noBranchPrediction;
|
||||
fcml_fnp_asm_optimizer _optimizer;
|
||||
fcml_uint16_t _optimizerFlags;
|
||||
fcml_fnp_asm_instruction_chooser _chooser;
|
||||
};
|
||||
|
||||
/** Assembler context.
|
||||
*
|
||||
* It is a counterpart to the fcml_st_assembler_context structure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class AssemblerContext {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerContext() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entry point instance for given operating mode
|
||||
* and optional instruction pointer.
|
||||
*
|
||||
* @param operatingMode The processor operating mode.
|
||||
* @param ip The instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerContext(EntryPoint::OperatingMode operatingMode, fcml_ip ip = 0) :
|
||||
_entryPoint(operatingMode, ip) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets constant assembler configuration associated with the context.
|
||||
*
|
||||
* @return Assembler configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const AssemblerConf& getConfig() const {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets assembler configuration associated with the context.
|
||||
*
|
||||
* @return Assembler configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerConf& getConfig() {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies given configuration to the instance associated with the context.
|
||||
* Deep copy is performed, so passed object not need to be maintained as
|
||||
* long as the context is used.
|
||||
*
|
||||
* @param config Configuration that is copied to the context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setConfig(const AssemblerConf &config) {
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference to the constant entry point instance
|
||||
* associated with the context.
|
||||
*
|
||||
* @return Reference to the constant entry point.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const EntryPoint& getEntryPoint() const {
|
||||
return _entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference to the entry point instance associated with the context.
|
||||
*
|
||||
* @return Reference to the entry point.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
EntryPoint& getEntryPoint() {
|
||||
return _entryPoint;
|
||||
}
|
||||
/**
|
||||
* Copies given entry point to the instance associated with the context.
|
||||
* Deep copy is performed, so passed object not need to be maintained as
|
||||
* long as the context is used.
|
||||
*
|
||||
* @param entryPoint The entry point.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setEntryPoint(const EntryPoint &entryPoint) {
|
||||
_entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets instruction pointer directly into the entry point.
|
||||
*
|
||||
* @param ip The new IP.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setIP(fcml_ip ip) {
|
||||
_entryPoint.setIP(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments entry point by given number of bytes.
|
||||
*
|
||||
* @param ip Number of bytes the instruction pointer
|
||||
* has to be incremented by.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void incrementIP(fcml_ip ip) {
|
||||
_entryPoint.incrementIP(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets processor operating mode directly into the entry point.
|
||||
*
|
||||
* @param operatingMode Processor operating mode to be set.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOperatingMode(EntryPoint::OperatingMode operatingMode) {
|
||||
_entryPoint.setOpMode(operatingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new address size attribute for the entry point.
|
||||
*
|
||||
* @param addressSizeAttribute The address size attribute.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setAddressSizeAttribute(fcml_usize addressSizeAttribute) {
|
||||
_entryPoint.setAddressSizeAttribute(addressSizeAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new operand size attribute for the entry point.
|
||||
*
|
||||
* @param operandSizeAttribute The operand size attribute.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOperandSizeAttribute(fcml_usize operandSizeAttribute) {
|
||||
_entryPoint.setOperandSizeAttribute(operandSizeAttribute);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Entry point associated with the context. */
|
||||
EntryPoint _entryPoint;
|
||||
/** Assembler configuration associated with the context. */
|
||||
AssemblerConf _config;
|
||||
|
||||
};
|
||||
|
||||
/** Converts objects to their structures counterparts.
|
||||
* @since 1.1.0
|
||||
* @remarks Internal API, not intended to be used outside.
|
||||
*/
|
||||
class AssemblerTypeConverter {
|
||||
public:
|
||||
|
||||
static void convert(const fcml_st_assembler_context &src,
|
||||
AssemblerContext &dest) {
|
||||
// Converts assembler configuration and entry point.
|
||||
// Both of them have dedicated conversion methods.
|
||||
convert(src.configuration, dest.getConfig());
|
||||
TypeConverter::convert(src.entry_point, dest.getEntryPoint());
|
||||
}
|
||||
|
||||
static void convert(const AssemblerContext &src,
|
||||
fcml_st_assembler_context &dest) {
|
||||
// Converts assembler configuration and entry point. Both of them
|
||||
// have dedicated conversion methods.
|
||||
convert(src.getConfig(), dest.configuration);
|
||||
TypeConverter::convert(src.getEntryPoint(), dest.entry_point);
|
||||
}
|
||||
|
||||
static void convert(const fcml_st_assembler_conf &src,
|
||||
AssemblerConf &dest) {
|
||||
dest.setChooseAbsEncoding(FCML_TO_CPP_BOOL(src.choose_abs_encoding));
|
||||
dest.setChooseSibEncoding(FCML_TO_CPP_BOOL(src.choose_sib_encoding));
|
||||
dest.setChooser(src.chooser);
|
||||
dest.setEnableErrorMessages(
|
||||
FCML_TO_CPP_BOOL(src.enable_error_messages));
|
||||
dest.setForceRexPrefix(FCML_TO_CPP_BOOL(src.force_rex_prefix));
|
||||
dest.setForceThreeByteVex(FCML_TO_CPP_BOOL(src.force_three_byte_VEX));
|
||||
dest.setIncrementIp(FCML_TO_CPP_BOOL(src.increment_ip));
|
||||
dest.setOptimizer(src.optimizer);
|
||||
dest.setOptimizerFlags(src.optimizer_flags);
|
||||
}
|
||||
|
||||
static void convert(const AssemblerConf &src,
|
||||
fcml_st_assembler_conf &dest) {
|
||||
dest.choose_abs_encoding = src.isChooseAbsEncoding();
|
||||
dest.choose_sib_encoding = src.isChooseSibEncoding();
|
||||
dest.chooser = src.getChooser();
|
||||
dest.enable_error_messages = src.isEnableErrorMessages();
|
||||
dest.force_rex_prefix = src.isForceRexPrefix();
|
||||
dest.force_three_byte_VEX = src.isForceThreeByteVex();
|
||||
dest.increment_ip = src.isIncrementIp();
|
||||
dest.optimizer = src.getOptimizer();
|
||||
dest.optimizer_flags = src.getOptimizerFlags();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* An assembler wrapper.
|
||||
* As you can see the assembler instance is managed internally
|
||||
* and is not exposed outside.
|
||||
* @since 1.1.0
|
||||
* @remarks This class is thread-safe.
|
||||
*/
|
||||
class Assembler: public NonCopyable, protected DialectAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an assembler instance for given dialect.
|
||||
*
|
||||
* @param dialect The dialect for the assembler instance.
|
||||
* @throw InitException Cannot initialize the assembler.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Assembler(Dialect &dialect) :
|
||||
_dialect(dialect) {
|
||||
fcml_ceh_error error = ::fcml_fn_assembler_init(extractDialect(dialect),
|
||||
&_assembler);
|
||||
if (error) {
|
||||
throw InitException(FCML_TEXT("Cannot initialize the assembler."),
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~Assembler() {
|
||||
if (_assembler) {
|
||||
::fcml_fn_assembler_free(_assembler);
|
||||
_assembler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Assembles given generic instruction model.
|
||||
*
|
||||
* @param ctx The assembler context.
|
||||
* @param instruction The generic instruction model to be assembled.
|
||||
* @param[out] result Assembler result.
|
||||
* @throw AssemblingFailedException Thrown if assembling fails
|
||||
* and AssemblerConf.isThrowExceptionOnError returns true.
|
||||
* @return Error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_ceh_error assemble(AssemblerContext &ctx,
|
||||
const Instruction &instruction, AssemblerResult &result) {
|
||||
|
||||
// Prepare assembler context.
|
||||
fcml_st_assembler_context context;
|
||||
AssemblerTypeConverter::convert(ctx, context);
|
||||
|
||||
context.assembler = _assembler;
|
||||
|
||||
// Prepare instruction.
|
||||
fcml_st_instruction inst;
|
||||
TypeConverter::convert(instruction, inst);
|
||||
|
||||
// Prepare assembler result.
|
||||
fcml_st_assembler_result res;
|
||||
::fcml_fn_assembler_result_prepare(&res);
|
||||
|
||||
fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR;
|
||||
|
||||
try {
|
||||
|
||||
result.clear();
|
||||
|
||||
error = ::fcml_fn_assemble(&context, &inst, &res);
|
||||
|
||||
// Free instruction mnemonic.
|
||||
TypeConverter::free(inst);
|
||||
|
||||
// Failed or not, convert assembler errors.
|
||||
ErrorContainer errorContainer;
|
||||
ErrorTypeConverter::convert(res.errors, errorContainer);
|
||||
|
||||
// Prepares assembler result.
|
||||
result.setErrorContainer(errorContainer);
|
||||
|
||||
if (error && ctx.getConfig().isThrowExceptionOnError()) {
|
||||
::fcml_fn_assembler_result_free(&res);
|
||||
throw AssemblingFailedException(FCML_TEXT("Assembling failed."),
|
||||
errorContainer, error);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
|
||||
std::vector<AssembledInstruction> &assembledInstructions =
|
||||
result.getAssembledInstructions();
|
||||
|
||||
assembledInstructions.clear();
|
||||
|
||||
if (res.number_of_instructions > 0) {
|
||||
ErrorContainer instructionWarnings;
|
||||
fcml_int i = 0;
|
||||
fcml_st_assembled_instruction *next_instruction =
|
||||
res.instructions;
|
||||
while (next_instruction) {
|
||||
fcml_st_ceh_error_container &instruction_warnings =
|
||||
next_instruction->warnings;
|
||||
ErrorTypeConverter::convert(instruction_warnings,
|
||||
instructionWarnings);
|
||||
AssembledInstruction assembledInstruction(
|
||||
next_instruction->code,
|
||||
next_instruction->code_length,
|
||||
instructionWarnings);
|
||||
assembledInstructions.push_back(assembledInstruction);
|
||||
if (next_instruction == res.chosen_instruction) {
|
||||
result.setChoosenInstructionIndex(i);
|
||||
}
|
||||
next_instruction = next_instruction->next;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert it back to the context because it might have been
|
||||
// modified during assembling process (IP incrementing etc).
|
||||
TypeConverter::convert(context.entry_point,
|
||||
ctx.getEntryPoint());
|
||||
|
||||
}
|
||||
|
||||
::fcml_fn_assembler_result_free(&res);
|
||||
|
||||
} catch (std::exception &exc) {
|
||||
// If anything failed, free assembler results.
|
||||
TypeConverter::free(inst);
|
||||
::fcml_fn_assembler_result_free(&res);
|
||||
throw exc;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets dialect associated with the assembler.
|
||||
* @return The dialect instance associated with the assembler.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Dialect& getDialect() const {
|
||||
return _dialect;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// A dialect used by the assembler.
|
||||
Dialect &_dialect;
|
||||
|
||||
// An initialized assembler instance.
|
||||
fcml_st_assembler *_assembler;
|
||||
|
||||
};
|
||||
|
||||
/** Iterates over machine code bytes from assembled instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class CodeIterator: public Iterator<fcml_uint8_t> {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a code iterator instance.
|
||||
* @param assembledInstructions Assembled instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
CodeIterator(std::vector<AssembledInstruction> &assembledInstructions) :
|
||||
_buffer(NULL), _len(0), _pos(0), _iterator(
|
||||
assembledInstructions.begin()), _assembledInstructions(
|
||||
assembledInstructions) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~CodeIterator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets true if there is an another element in the iterator.
|
||||
*
|
||||
* @return True if there is another byte in the iterator.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool hasNext() {
|
||||
if (_buffer && _pos >= _len) {
|
||||
_buffer = NULL;
|
||||
}
|
||||
if (!_buffer) {
|
||||
if (_iterator == _assembledInstructions.end()) {
|
||||
return false;
|
||||
}
|
||||
AssembledInstruction ¤t = *_iterator++;
|
||||
_buffer = current.getCode();
|
||||
_len = current.getCodeLength();
|
||||
_pos = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next element from the iterator.
|
||||
*
|
||||
* @return Next machine code byte.
|
||||
* @throw IllegalStateException If iterator is empty.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_uint8_t next() {
|
||||
if ((!_buffer || _pos >= _len) && !hasNext()) {
|
||||
throw IllegalStateException(
|
||||
FCML_TEXT("No more elements in the iterator."));
|
||||
}
|
||||
return _buffer[_pos++];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Code of the current instruction iterator points to. */
|
||||
const fcml_uint8_t *_buffer;
|
||||
/** Code length in bytes. */
|
||||
fcml_usize _len;
|
||||
/** Position in the code buffer */
|
||||
fcml_usize _pos;
|
||||
/** Assembled instructions iterator. */
|
||||
std::vector<AssembledInstruction>::iterator _iterator;
|
||||
/** Vector with assembled instructions. */
|
||||
std::vector<AssembledInstruction> &_assembledInstructions;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //FCML_ASSEMBLER_HPP_
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_choosers.h
|
||||
*
|
||||
* API for instruction choosers.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_CHOOSER_H_
|
||||
#define FCML_CHOOSER_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Returns next instructions from the iterator.
|
||||
* Instruction chooser uses this function to get next instruction from the chain.
|
||||
* @param instruction Current instruction.
|
||||
*/
|
||||
typedef fcml_ptr (*fcml_fnp_chooser_next)(fcml_ptr instruction);
|
||||
|
||||
/** Gets instruction code from current abstract instruction pointer.
|
||||
* Gets instruction pointer and fills given instruction code
|
||||
* holder with the binary code of the instruction.
|
||||
* @param instruction Instruction pointer.
|
||||
* @param instruction_code Holder for the instruction code.
|
||||
*/
|
||||
typedef void (*fcml_fnp_chooser_extract)(fcml_ptr instruction,
|
||||
fcml_st_instruction_code *instruction_code);
|
||||
|
||||
/** Instruction chooser context used to communicate with environment. */
|
||||
typedef struct fcml_st_chooser_context {
|
||||
/** First instruction in the chain. */
|
||||
fcml_ptr instruction;
|
||||
/** Gets next instruction code from iterator. */
|
||||
fcml_fnp_chooser_next next;
|
||||
/** Extracts instruction code from abstract instruction pointer.*/
|
||||
fcml_fnp_chooser_extract extract;
|
||||
} fcml_st_chooser_context;
|
||||
|
||||
/** Instruction chooser function pointer declaration.
|
||||
* @param chooser_context Instruction chooser context.
|
||||
*/
|
||||
typedef fcml_ptr (LIB_CALL *fcml_fnp_asm_instruction_chooser)(
|
||||
fcml_st_chooser_context *chooser_context);
|
||||
|
||||
/** Default instruction chooser which chooses the shortest instruction available.
|
||||
* @param chooser_context Instruction chooser context.
|
||||
*/
|
||||
fcml_ptr LIB_EXPORT LIB_CALL fcml_fn_asm_default_instruction_chooser(
|
||||
fcml_st_chooser_context *chooser_context);
|
||||
|
||||
/** NULL chooser which do not chose anything.
|
||||
* @param chooser_context Instruction chooser context.
|
||||
*/
|
||||
fcml_ptr LIB_EXPORT LIB_CALL fcml_fn_asm_no_instruction_chooser(
|
||||
fcml_st_chooser_context *chooser_context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_CHOOSER_H_ */
|
@ -0,0 +1,832 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_common.h
|
||||
* Definitions of common structures used by FCML components.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_INT_COMMON_H_
|
||||
#define FCML_INT_COMMON_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_instructions.h"
|
||||
|
||||
/** Maximal number of the instruction operands. */
|
||||
#define FCML_OPERANDS_COUNT 5
|
||||
/** Maximal number of bytes instruction can use. */
|
||||
#define FCML_INSTRUCTION_SIZE 15
|
||||
/** Number of opcode bytes. */
|
||||
#define FCML_OPCODES_NUM 3
|
||||
|
||||
/**
|
||||
* @defgroup PREFIX_GROUP Explicit prefixes
|
||||
* List of prefixes that can be explicitly defined for instruction.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** LOCK prefix (0xF0)*/
|
||||
#define FCML_PREFIX_LOCK 0x0001
|
||||
/** REPNE prefix (0xF2) */
|
||||
#define FCML_PREFIX_REPNE 0x0002
|
||||
/** REPNZ prefix (0xF2) */
|
||||
#define FCML_PREFIX_REPNZ FCML_PREFIX_REPNE
|
||||
/** REP prefix (0xF3) */
|
||||
#define FCML_PREFIX_REP 0x0004
|
||||
/** REPE prefix (0xF3) */
|
||||
#define FCML_PREFIX_REPE FCML_PREFIX_REP
|
||||
/** REPZ prefix (0xF3) */
|
||||
#define FCML_PREFIX_REPZ FCML_PREFIX_REP
|
||||
/** XACQUIRE prefix (0xF2) */
|
||||
#define FCML_PREFIX_XACQUIRE 0x0008
|
||||
/** XRELEASE prefix (0xF3) */
|
||||
#define FCML_PREFIX_XRELEASE 0x0010
|
||||
/** branch hint (0x2E) (SSE2 extension)*/
|
||||
#define FCML_PREFIX_BRANCH_HINT 0x0020
|
||||
/** nobranch hint (0x3E) (SSE2 extension)*/
|
||||
#define FCML_PREFIX_NOBRANCH_HINT 0x0040
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Supported processor operating modes.
|
||||
*/
|
||||
typedef enum fcml_en_operating_mode {
|
||||
/** Real-addressing mode, virtual 8086 mode. */
|
||||
FCML_OM_16_BIT = 1,
|
||||
/** Protected/Compatibility mode when 'D' segment descriptor
|
||||
* flag is set to 1. */
|
||||
FCML_OM_32_BIT,
|
||||
/** 64-bit mode. ('L' flag of segment descriptor set to 1.) */
|
||||
FCML_OM_64_BIT,
|
||||
} fcml_en_operating_mode;
|
||||
|
||||
/* Simple types. */
|
||||
|
||||
/** Type used for storing instruction and operand hint masks. */
|
||||
typedef fcml_uint16_t fcml_hints;
|
||||
|
||||
/**
|
||||
* Type for explicit instruction prefixes bit mask.
|
||||
*/
|
||||
typedef fcml_uint16_t fcml_prefixes;
|
||||
|
||||
/**
|
||||
* General instruction pointer holder.
|
||||
*/
|
||||
typedef fcml_int64_t fcml_ip;
|
||||
|
||||
/* Register numbers.*/
|
||||
|
||||
/**
|
||||
* @defgroup REGISTERS_GROUP Registers.
|
||||
* All supported x64_64 registers are defined here.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FCML_REG_AL 0
|
||||
#define FCML_REG_AX 0
|
||||
#define FCML_REG_EAX 0
|
||||
#define FCML_REG_RAX 0
|
||||
#define FCML_REG_MM0 0
|
||||
#define FCML_REG_XMM0 0
|
||||
#define FCML_REG_YMM0 0
|
||||
#define FCML_REG_ZMM0 0
|
||||
|
||||
#define FCML_REG_CL 1
|
||||
#define FCML_REG_CX 1
|
||||
#define FCML_REG_ECX 1
|
||||
#define FCML_REG_RCX 1
|
||||
#define FCML_REG_MM1 1
|
||||
#define FCML_REG_XMM1 1
|
||||
#define FCML_REG_YMM1 1
|
||||
#define FCML_REG_ZMM1 1
|
||||
|
||||
#define FCML_REG_DL 2
|
||||
#define FCML_REG_DX 2
|
||||
#define FCML_REG_EDX 2
|
||||
#define FCML_REG_RDX 2
|
||||
#define FCML_REG_MM2 2
|
||||
#define FCML_REG_XMM2 2
|
||||
#define FCML_REG_YMM2 2
|
||||
#define FCML_REG_ZMM2 2
|
||||
|
||||
#define FCML_REG_BL 3
|
||||
#define FCML_REG_BX 3
|
||||
#define FCML_REG_EBX 3
|
||||
#define FCML_REG_RBX 3
|
||||
#define FCML_REG_MM3 3
|
||||
#define FCML_REG_XMM3 3
|
||||
#define FCML_REG_YMM3 3
|
||||
#define FCML_REG_ZMM3 3
|
||||
|
||||
#define FCML_REG_AH 4
|
||||
#define FCML_REG_SP 4
|
||||
#define FCML_REG_SPL 4
|
||||
#define FCML_REG_ESP 4
|
||||
#define FCML_REG_RSP 4
|
||||
#define FCML_REG_MM4 4
|
||||
#define FCML_REG_XMM4 4
|
||||
#define FCML_REG_YMM4 4
|
||||
#define FCML_REG_ZMM4 4
|
||||
|
||||
#define FCML_REG_CH 5
|
||||
#define FCML_REG_BP 5
|
||||
#define FCML_REG_BPL 5
|
||||
#define FCML_REG_EBP 5
|
||||
#define FCML_REG_RBP 5
|
||||
#define FCML_REG_MM5 5
|
||||
#define FCML_REG_XMM5 5
|
||||
#define FCML_REG_YMM5 5
|
||||
#define FCML_REG_ZMM5 5
|
||||
|
||||
#define FCML_REG_DH 6
|
||||
#define FCML_REG_SI 6
|
||||
#define FCML_REG_SIL 6
|
||||
#define FCML_REG_ESI 6
|
||||
#define FCML_REG_RSI 6
|
||||
#define FCML_REG_MM6 6
|
||||
#define FCML_REG_XMM6 6
|
||||
#define FCML_REG_YMM6 6
|
||||
#define FCML_REG_ZMM6 6
|
||||
|
||||
#define FCML_REG_BH 7
|
||||
#define FCML_REG_DI 7
|
||||
#define FCML_REG_DIL 7
|
||||
#define FCML_REG_EDI 7
|
||||
#define FCML_REG_RDI 7
|
||||
#define FCML_REG_MM7 7
|
||||
#define FCML_REG_XMM7 7
|
||||
#define FCML_REG_YMM7 7
|
||||
#define FCML_REG_ZMM7 7
|
||||
|
||||
#define FCML_REG_R8L 8
|
||||
#define FCML_REG_R8W 8
|
||||
#define FCML_REG_R8D 8
|
||||
#define FCML_REG_R8 8
|
||||
#define FCML_REG_XMM8 8
|
||||
#define FCML_REG_YMM8 8
|
||||
#define FCML_REG_ZMM8 8
|
||||
|
||||
#define FCML_REG_R9L 9
|
||||
#define FCML_REG_R9W 9
|
||||
#define FCML_REG_R9D 9
|
||||
#define FCML_REG_R9 9
|
||||
#define FCML_REG_XMM9 9
|
||||
#define FCML_REG_YMM9 9
|
||||
#define FCML_REG_ZMM9 9
|
||||
|
||||
#define FCML_REG_R10L 10
|
||||
#define FCML_REG_R10W 10
|
||||
#define FCML_REG_R10D 10
|
||||
#define FCML_REG_R10 10
|
||||
#define FCML_REG_XMM10 10
|
||||
#define FCML_REG_YMM10 10
|
||||
#define FCML_REG_ZMM10 10
|
||||
|
||||
#define FCML_REG_R11L 11
|
||||
#define FCML_REG_R11W 11
|
||||
#define FCML_REG_R11D 11
|
||||
#define FCML_REG_R11 11
|
||||
#define FCML_REG_XMM11 11
|
||||
#define FCML_REG_YMM11 11
|
||||
#define FCML_REG_ZMM11 11
|
||||
|
||||
#define FCML_REG_R12L 12
|
||||
#define FCML_REG_R12W 12
|
||||
#define FCML_REG_R12D 12
|
||||
#define FCML_REG_R12 12
|
||||
#define FCML_REG_XMM12 12
|
||||
#define FCML_REG_YMM12 12
|
||||
#define FCML_REG_ZMM12 12
|
||||
|
||||
#define FCML_REG_R13L 13
|
||||
#define FCML_REG_R13W 13
|
||||
#define FCML_REG_R13D 13
|
||||
#define FCML_REG_R13 13
|
||||
#define FCML_REG_XMM13 13
|
||||
#define FCML_REG_YMM13 13
|
||||
#define FCML_REG_ZMM13 13
|
||||
|
||||
#define FCML_REG_R14L 14
|
||||
#define FCML_REG_R14W 14
|
||||
#define FCML_REG_R14D 14
|
||||
#define FCML_REG_R14 14
|
||||
#define FCML_REG_XMM14 14
|
||||
#define FCML_REG_YMM14 14
|
||||
#define FCML_REG_ZMM14 14
|
||||
|
||||
#define FCML_REG_R15L 15
|
||||
#define FCML_REG_R15W 15
|
||||
#define FCML_REG_R15D 15
|
||||
#define FCML_REG_R15 15
|
||||
#define FCML_REG_XMM15 15
|
||||
#define FCML_REG_YMM15 15
|
||||
#define FCML_REG_ZMM15 15
|
||||
|
||||
#define FCML_REG_XMM16 16
|
||||
#define FCML_REG_YMM16 16
|
||||
#define FCML_REG_ZMM16 16
|
||||
|
||||
#define FCML_REG_XMM17 17
|
||||
#define FCML_REG_YMM17 17
|
||||
#define FCML_REG_ZMM17 17
|
||||
|
||||
#define FCML_REG_XMM18 18
|
||||
#define FCML_REG_YMM18 18
|
||||
#define FCML_REG_ZMM18 18
|
||||
|
||||
#define FCML_REG_XMM19 19
|
||||
#define FCML_REG_YMM19 19
|
||||
#define FCML_REG_ZMM19 19
|
||||
|
||||
#define FCML_REG_XMM20 20
|
||||
#define FCML_REG_YMM20 20
|
||||
#define FCML_REG_ZMM20 20
|
||||
|
||||
#define FCML_REG_XMM21 21
|
||||
#define FCML_REG_YMM21 21
|
||||
#define FCML_REG_ZMM21 21
|
||||
|
||||
#define FCML_REG_XMM22 22
|
||||
#define FCML_REG_YMM22 22
|
||||
#define FCML_REG_ZMM22 22
|
||||
|
||||
#define FCML_REG_XMM23 23
|
||||
#define FCML_REG_YMM23 23
|
||||
#define FCML_REG_ZMM23 23
|
||||
|
||||
#define FCML_REG_XMM24 24
|
||||
#define FCML_REG_YMM24 24
|
||||
#define FCML_REG_ZMM24 24
|
||||
|
||||
#define FCML_REG_XMM25 25
|
||||
#define FCML_REG_YMM25 25
|
||||
#define FCML_REG_ZMM25 25
|
||||
|
||||
#define FCML_REG_XMM26 26
|
||||
#define FCML_REG_YMM26 26
|
||||
#define FCML_REG_ZMM26 26
|
||||
|
||||
#define FCML_REG_XMM27 27
|
||||
#define FCML_REG_YMM27 27
|
||||
#define FCML_REG_ZMM27 27
|
||||
|
||||
#define FCML_REG_XMM28 28
|
||||
#define FCML_REG_YMM28 28
|
||||
#define FCML_REG_ZMM28 28
|
||||
|
||||
#define FCML_REG_XMM29 29
|
||||
#define FCML_REG_YMM29 29
|
||||
#define FCML_REG_ZMM29 29
|
||||
|
||||
#define FCML_REG_XMM30 30
|
||||
#define FCML_REG_YMM30 30
|
||||
#define FCML_REG_ZMM30 30
|
||||
|
||||
#define FCML_REG_XMM31 31
|
||||
#define FCML_REG_YMM31 31
|
||||
#define FCML_REG_ZMM31 31
|
||||
|
||||
/* Segment registers. */
|
||||
|
||||
#define FCML_REG_ES 0
|
||||
#define FCML_REG_CS 1
|
||||
#define FCML_REG_SS 2
|
||||
#define FCML_REG_DS 3
|
||||
#define FCML_REG_FS 4
|
||||
#define FCML_REG_GS 5
|
||||
|
||||
/* FPU registers */
|
||||
|
||||
#define FCML_REG_ST0 0
|
||||
#define FCML_REG_ST1 1
|
||||
#define FCML_REG_ST2 2
|
||||
#define FCML_REG_ST3 3
|
||||
#define FCML_REG_ST4 4
|
||||
#define FCML_REG_ST5 5
|
||||
#define FCML_REG_ST6 6
|
||||
#define FCML_REG_ST7 7
|
||||
|
||||
/* Control registers. */
|
||||
|
||||
#define FCML_REG_CR0 0
|
||||
#define FCML_REG_CR2 2
|
||||
#define FCML_REG_CR3 3
|
||||
#define FCML_REG_CR4 4
|
||||
#define FCML_REG_CR8 8
|
||||
|
||||
/* Debug register. */
|
||||
|
||||
#define FCML_REG_DR0 0
|
||||
#define FCML_REG_DR1 1
|
||||
#define FCML_REG_DR2 2
|
||||
#define FCML_REG_DR3 3
|
||||
#define FCML_REG_DR4 4
|
||||
#define FCML_REG_DR5 5
|
||||
#define FCML_REG_DR6 6
|
||||
#define FCML_REG_DR7 7
|
||||
|
||||
/* Opmask registers. */
|
||||
|
||||
#define FCML_REG_K0 0
|
||||
#define FCML_REG_K1 1
|
||||
#define FCML_REG_K2 2
|
||||
#define FCML_REG_K3 3
|
||||
#define FCML_REG_K4 4
|
||||
#define FCML_REG_K5 5
|
||||
#define FCML_REG_K6 6
|
||||
#define FCML_REG_K7 7
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup DATA_SIZE_GROUP Constants used to describe data size.
|
||||
* @{instrunction->hints
|
||||
*/
|
||||
|
||||
#define FCML_DS_UNDEF 0
|
||||
#define FCML_DS_8 8
|
||||
#define FCML_DS_16 16
|
||||
#define FCML_DS_32 32
|
||||
#define FCML_DS_64 64
|
||||
#define FCML_DS_128 128
|
||||
#define FCML_DS_256 256
|
||||
#define FCML_DS_512 512
|
||||
|
||||
/** @} */
|
||||
|
||||
/* Size operators. */
|
||||
|
||||
#define FCML_OS_UNDEFINED 0
|
||||
#define FCML_OS_BYTE 8
|
||||
#define FCML_OS_WORD 16
|
||||
#define FCML_OS_DWORD 32
|
||||
#define FCML_OS_FWORD 48
|
||||
#define FCML_OS_QWORD 64
|
||||
#define FCML_OS_MWORD 64
|
||||
#define FCML_OS_TBYTE 80
|
||||
#define FCML_OS_OWORD 128
|
||||
#define FCML_OS_XWORD 128
|
||||
#define FCML_OS_YWORD 256
|
||||
#define FCML_OS_ZWORD 512
|
||||
|
||||
/* SIMD tuple types. */
|
||||
|
||||
/* Instructions affected by embedded broadcast */
|
||||
#define FCML_TT_NONE 0
|
||||
#define FCML_TT_FV 1
|
||||
#define FCML_TT_HV 2
|
||||
|
||||
/* Instructions not affected by embedded broadcast */
|
||||
#define FCML_TT_FVM 3 /* Full Mem */
|
||||
#define FCML_TT_T1S 4
|
||||
#define FCML_TT_T1F 5
|
||||
#define FCML_TT_T2 6
|
||||
#define FCML_TT_T4 7
|
||||
#define FCML_TT_T8 8
|
||||
#define FCML_TT_HVM 9
|
||||
#define FCML_TT_QVM 10
|
||||
#define FCML_TT_OVM 11
|
||||
#define FCML_TT_M128 12
|
||||
#define FCML_TT_DUP 13
|
||||
#define FCML_TT_T1x4 14 /* Tuple1_4X */
|
||||
|
||||
/* Embedded rounding mode. */
|
||||
|
||||
#define FCML_ER_RN_SAE 0
|
||||
#define FCML_ER_RD_SAE 1
|
||||
#define FCML_ER_RU_SAE 2
|
||||
#define FCML_ER_RZ_SAE 3
|
||||
|
||||
/**
|
||||
* Register type.
|
||||
* Every register is represented as an integer value and it's
|
||||
* register type. This enumeration provides all supported register types.
|
||||
*/
|
||||
typedef enum fcml_en_register {
|
||||
/** Undefined register type. */
|
||||
FCML_REG_UNDEFINED = 0,
|
||||
/** General purpose register. */
|
||||
FCML_REG_GPR,
|
||||
/** SIMD (SSE, MMX) register. */
|
||||
FCML_REG_SIMD,
|
||||
/** FPU register. */
|
||||
FCML_REG_FPU,
|
||||
/** Segment register */
|
||||
FCML_REG_SEG,
|
||||
/** Control register. */
|
||||
FCML_REG_CR,
|
||||
/** Debug register */
|
||||
FCML_REG_DR,
|
||||
/** Instruction pointer register. Used for relative RIP addressing. */
|
||||
FCML_REG_IP,
|
||||
/** Operand mask register. */
|
||||
FCML_REG_OPMASK
|
||||
} fcml_en_register;
|
||||
|
||||
/**
|
||||
* Structure describes x86_64 register.
|
||||
*/
|
||||
typedef struct fcml_st_register {
|
||||
/** Register type. */
|
||||
fcml_en_register type;
|
||||
/** Register size in bits. */
|
||||
fcml_usize size;
|
||||
/** Register itself as a positive integer. @see REGISTERS_GROUP */
|
||||
fcml_uint8_t reg;
|
||||
/** In case of SPL,BPL,SIL,DIL GPR registers has to be set to true. */
|
||||
fcml_bool x64_exp;
|
||||
} fcml_st_register;
|
||||
|
||||
/*********************************
|
||||
* Conditions.
|
||||
*********************************/
|
||||
|
||||
/** Number of supported condition types. */
|
||||
#define FCML_NUMBER_OF_CONDITIONS 8
|
||||
|
||||
/**
|
||||
* Condition type.
|
||||
* Every conditional instruction has an appropriate condition type set.
|
||||
* Following enumeration defines all supported types.
|
||||
*/
|
||||
typedef enum fcml_en_condition_type {
|
||||
/** 0 Overflow*/
|
||||
FCML_CONDITION_O = 0,
|
||||
/** 1 Below*/
|
||||
FCML_CONDITION_B,
|
||||
/** 2 Equal*/
|
||||
FCML_CONDITION_E,
|
||||
/** 3 Below or equal*/
|
||||
FCML_CONDITION_BE,
|
||||
/** 4 Sign*/
|
||||
FCML_CONDITION_S,
|
||||
/** 5 Parity*/
|
||||
FCML_CONDITION_P,
|
||||
/** 6 Less than*/
|
||||
FCML_CONDITION_L,
|
||||
/** 7 Less than or equal to*/
|
||||
FCML_CONDITION_LE
|
||||
} fcml_en_condition_type;
|
||||
|
||||
/**
|
||||
* Defines instruction's condition.
|
||||
*/
|
||||
typedef struct fcml_st_condition {
|
||||
/* Condition type.*/
|
||||
fcml_en_condition_type condition_type;
|
||||
/* True if condition should be negated.*/
|
||||
fcml_bool is_negation;
|
||||
} fcml_st_condition;
|
||||
|
||||
/*********************************
|
||||
* Size attributes flags.
|
||||
*********************************/
|
||||
|
||||
/**
|
||||
* @defgroup SUPPORTED_SIZE_GROUP These values can be used in order to
|
||||
* prepare a mask of supported sizes. Used mainly by optimizers where
|
||||
* instructions can be assembled using different attribute sizes.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define FCML_EN_ASF_ANY 0x00
|
||||
#define FCML_EN_ASF_16 0x01
|
||||
#define FCML_EN_ASF_32 0x02
|
||||
#define FCML_EN_ASF_64 0x04
|
||||
#define FCML_EN_ASF_ALL FCML_EN_ASF_16 | FCML_EN_ASF_32 | FCML_EN_ASF_64
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Nullable wrapper for mask of size flags.
|
||||
*/
|
||||
typedef struct fcml_st_nullable_size_flags {
|
||||
/** True if mask is set. */
|
||||
fcml_bool is_set;
|
||||
/** Mask of supported size values. */
|
||||
fcml_flags flags;
|
||||
} fcml_st_nullable_size_flags;
|
||||
|
||||
/*********************************
|
||||
* Operands.
|
||||
*********************************/
|
||||
|
||||
/**
|
||||
* Operand access mode.
|
||||
*/
|
||||
typedef enum fcml_en_access_mode {
|
||||
/** Undefined mode. */
|
||||
FCML_AM_ACCESS_MODE_UNDEFINED = 0,
|
||||
/** Operand is read by instruction. */
|
||||
FCML_AM_READ = 0x01,
|
||||
/** Operand is set by instruction */
|
||||
FCML_AM_WRITE = 0x02,
|
||||
/** Operand is read but can be also set. */
|
||||
FCML_AM_READ_WRITE = FCML_AM_READ | FCML_AM_WRITE
|
||||
} fcml_en_access_mode;
|
||||
|
||||
/**
|
||||
* Representation of far pointer operand.
|
||||
*/
|
||||
typedef struct fcml_st_far_pointer {
|
||||
/** 16-bit Code segment. */
|
||||
fcml_uint16_t segment;
|
||||
/** Size of the offset. */
|
||||
fcml_usize offset_size;
|
||||
/** 16-bit offset. */
|
||||
fcml_int16_t offset16;
|
||||
/** 32-bit offset. */
|
||||
fcml_int32_t offset32;
|
||||
} fcml_st_far_pointer;
|
||||
|
||||
/********************************************/
|
||||
/** Memory addressing using ModR/M field **/
|
||||
/********************************************/
|
||||
|
||||
/**
|
||||
* Addressing form.
|
||||
* Distinguish between two types of addressing forms: effective addressing
|
||||
* and explicit absolute offset.
|
||||
*/
|
||||
typedef enum fcml_en_address_form {
|
||||
/** Default value set if memory addressing hasn't been configured. */
|
||||
FCML_AF_UNDEFINED,
|
||||
/** Absolute offset (address). */
|
||||
FCML_AF_OFFSET,
|
||||
/** Effective address combined from address components like base register,
|
||||
* index registers, factor, displacement etc... */
|
||||
FCML_AF_COMBINED
|
||||
} fcml_en_effective_address_form;
|
||||
|
||||
/**
|
||||
* Absolute offset.
|
||||
*/
|
||||
typedef struct fcml_st_offset {
|
||||
/** Offset size 16,32 or 64 bits. */
|
||||
fcml_usize size;
|
||||
/** True if offset should be treated as signed value. */
|
||||
fcml_bool is_signed;
|
||||
/** Place for 16-bit absolute offset. */
|
||||
fcml_int16_t off16;
|
||||
/** Place for 32-bit absolute offset. */
|
||||
fcml_int32_t off32;
|
||||
/** Place for 64-bit absolute offset. */
|
||||
fcml_int64_t off64;
|
||||
} fcml_st_offset;
|
||||
|
||||
/**
|
||||
* Effective address.
|
||||
*/
|
||||
typedef struct fcml_st_effective_address {
|
||||
/** GPR base register. @see fcml_st_register. */
|
||||
fcml_st_register base;
|
||||
/** GPR index register. @see fcml_st_register. */
|
||||
fcml_st_register index;
|
||||
/** Scale factor 1,2,4 or 8. */
|
||||
fcml_uint8_t scale_factor;
|
||||
/** Displacement value. @see fcml_st_integer. */
|
||||
fcml_st_integer displacement;
|
||||
} fcml_st_effective_address;
|
||||
|
||||
/**
|
||||
* Describes segment register.
|
||||
*/
|
||||
typedef struct fcml_st_segment_selector {
|
||||
/** Used segment register. @see fcml_st_register*/
|
||||
fcml_st_register segment_selector;
|
||||
/** Set to true if given segment register is a default one in given
|
||||
* context. This value is set by disassembler.
|
||||
*/
|
||||
fcml_bool is_default_reg;
|
||||
} fcml_st_segment_selector;
|
||||
|
||||
/**
|
||||
* Generic memory addressing operator.
|
||||
*/
|
||||
typedef struct fcml_st_address {
|
||||
/** Size of data accessed in memory.*/
|
||||
fcml_usize size_operator;
|
||||
/** Memory addressing format: absolute offset/effective address.
|
||||
* @see fcml_en_effective_address_form
|
||||
*/
|
||||
fcml_en_effective_address_form address_form;
|
||||
/** Segment register.*/
|
||||
fcml_st_segment_selector segment_selector;
|
||||
/** Memory address for FCML_AF_COMBINED form.*/
|
||||
fcml_st_effective_address effective_address;
|
||||
/** Memory address for FCML_AF_OFFSET form.*/
|
||||
fcml_st_offset offset;
|
||||
} fcml_st_address;
|
||||
|
||||
/**
|
||||
* Rounding mode.
|
||||
*/
|
||||
typedef enum fcml_en_embeeded_rounding_control {
|
||||
FCML_ERC_RNE, FCML_ERC_RD, FCML_ERC_RU, FCML_ERC_RZ
|
||||
} fcml_en_embeeded_rounding_control;
|
||||
|
||||
/**
|
||||
* Container for operand decorators.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
typedef struct fcml_st_operand_decorators {
|
||||
/** Broadcasting: 2, 4, 8, 16, 32, 64. */
|
||||
fcml_nuint8_t bcast;
|
||||
/** Zeroing masking. */
|
||||
fcml_bool z;
|
||||
/** The 64-bit k registers are: k0 through k7. */
|
||||
fcml_st_register operand_mask_reg;
|
||||
/** Embedded rounding control. */
|
||||
fcml_nuint8_t er;
|
||||
/** Indicates support for SAE (Suppress All Exceptions). */
|
||||
fcml_bool sae;
|
||||
} fcml_st_operand_decorators;
|
||||
|
||||
/**
|
||||
* Supported operand types.
|
||||
*/
|
||||
typedef enum fcml_en_operand_type {
|
||||
/** Operand not used. */
|
||||
FCML_OT_NONE,
|
||||
/** Immediate integer value. */
|
||||
FCML_OT_IMMEDIATE,
|
||||
/** Direct far pointer. */
|
||||
FCML_OT_FAR_POINTER,
|
||||
/** Memory address. */
|
||||
FCML_OT_ADDRESS,
|
||||
/** Processor register. */
|
||||
FCML_OT_REGISTER,
|
||||
/**
|
||||
* Not an operand in a strict sense,
|
||||
* only a container for attributes.
|
||||
*/
|
||||
FCML_OT_VIRTUAL
|
||||
} fcml_en_operand_type;
|
||||
|
||||
/**
|
||||
* Operand hints.
|
||||
* Hints dedicated for instruction operands.
|
||||
*/
|
||||
typedef enum fcml_en_operand_hints {
|
||||
/**
|
||||
* Undefined.
|
||||
*/
|
||||
FCML_OP_HINT_UNDEFIEND = 0x0000,
|
||||
/**
|
||||
* SIMD operand. All operands which uses SIMD registers (mmx, xmm, ymm)
|
||||
* have this flag set. It is for instance used by Intel syntax renderer
|
||||
* for data size operators (mmword ptr, xmmword ptr, ymmword ptr).
|
||||
*/
|
||||
FCML_OP_HINT_MULTIMEDIA_INSTRUCTION = 0x0001,
|
||||
/**
|
||||
* Relative address. Flags set for all branches which use jumps
|
||||
* calculated by displacement relative to the IP of the next instructions.
|
||||
*/
|
||||
FCML_OP_HINT_DISPLACEMENT_RELATIVE_ADDRESS = 0x0002,
|
||||
/**
|
||||
* Pseudo opcode. Hint set for last operand (Intel syntax) which contains
|
||||
* comparison predicate of the following instructions: CMPSD, VCMPSD, CMPSS,
|
||||
* VCMPSS, VPCOMB, VPCOMW, VPCOMD, VPCOMQ, VPCOMUB, VPCOMUW,
|
||||
* VPCOMUD, VPCOMUQ.
|
||||
*/
|
||||
FCML_OP_HINT_PSEUDO_OPCODE = 0x0004,
|
||||
/**
|
||||
* Offset should be encoded as absolute address.
|
||||
*/
|
||||
FCML_OP_HINT_ABSOLUTE_ADDRESSING = 0x0008,
|
||||
/**
|
||||
* Offset should be encoded as relative address.
|
||||
*/
|
||||
FCML_OP_HINT_RELATIVE_ADDRESSING = 0x0010,
|
||||
/**
|
||||
* Encode ModR/M with optional SIB byte if possible.
|
||||
**/
|
||||
FCML_OP_HINT_SIB_ENCODING = 0x0020
|
||||
} fcml_en_operand_hints;
|
||||
|
||||
/** Instruction operand.
|
||||
* Structure represents one instruction operand.
|
||||
*/
|
||||
typedef struct fcml_st_operand {
|
||||
/** Operand type */
|
||||
fcml_en_operand_type type;
|
||||
/** Optional operand level hints. */
|
||||
fcml_hints hints;
|
||||
/** Immediate value operand. */
|
||||
fcml_st_integer immediate;
|
||||
/** Far pointer operand. */
|
||||
fcml_st_far_pointer far_pointer;
|
||||
/** Effective address or absolute offset. */
|
||||
fcml_st_address address;
|
||||
/** Register operand. */
|
||||
fcml_st_register reg;
|
||||
/** Operand decorators. */
|
||||
fcml_st_operand_decorators decorators;
|
||||
} fcml_st_operand;
|
||||
|
||||
/*********************************
|
||||
* Instruction definition.
|
||||
*********************************/
|
||||
|
||||
/**
|
||||
* Instruction level hints.
|
||||
* Set of the hints that can be only defined on the
|
||||
* level of the whole instruction. They can not be used
|
||||
* with operands.
|
||||
*/
|
||||
typedef enum fcml_en_instruction_hints {
|
||||
/** No hints defined. */
|
||||
FCML_HINT_NO_HINTS,
|
||||
/** Hints instruction to use FAR pointer to address the memory. */
|
||||
FCML_HINT_FAR_POINTER = 0x0001,
|
||||
/** Hints instruction to use NEAR pointer to address the memory. */
|
||||
FCML_HINT_NEAR_POINTER = 0x0002,
|
||||
/** This hint is used only by assembler in order to force it to generate
|
||||
* three byte VEX/XOP prefix even if prefix fields fits into two bytes. */
|
||||
FCML_HINT_LONG_FORM_POINTER = 0x0004,
|
||||
/** Hints instruction to use INDIRECT pointer to address the memory. */
|
||||
FCML_HINT_INDIRECT_POINTER = 0x0008,
|
||||
/** Hints instruction to use DIRECT memory addressing. */
|
||||
FCML_HINT_DIRECT_POINTER = 0x0010
|
||||
} fcml_en_instruction_hints;
|
||||
|
||||
/**
|
||||
* Generic instruction model.
|
||||
* Generic instruction model (GIM) is a common structure used to describe
|
||||
* instruction in a common way used by FCML assembler and disassembler.
|
||||
*/
|
||||
typedef struct fcml_st_instruction {
|
||||
/** Describes explicit instruction prefixes. @ref PREFIX_GROUP "List
|
||||
* of explicit prefixes." */
|
||||
fcml_prefixes prefixes;
|
||||
/** Holds instruction level hints. */
|
||||
fcml_hints hints;
|
||||
/** Dialect-dependent instruction mnemonic.
|
||||
* @see fcml_en_instruction_hints */
|
||||
fcml_char *mnemonic;
|
||||
/** True for conditional instructions. */
|
||||
fcml_bool is_conditional;
|
||||
/** Describes condition used by assembled/disassembled
|
||||
* conditional instruction. */
|
||||
fcml_st_condition condition;
|
||||
/** Fixed size array of instruction operands. */
|
||||
fcml_st_operand operands[FCML_OPERANDS_COUNT];
|
||||
/** Number of operands defined for instruction. */
|
||||
fcml_int operands_count;
|
||||
} fcml_st_instruction;
|
||||
|
||||
/*********************************
|
||||
* Instruction definition.
|
||||
*********************************/
|
||||
|
||||
/**
|
||||
* An encoded instruction.
|
||||
*/
|
||||
typedef struct fcml_st_instruction_code {
|
||||
/** Pointer to the instruction code. */
|
||||
fcml_uint8_t *code;
|
||||
/** Instruction code length. */
|
||||
fcml_usize code_length;
|
||||
} fcml_st_instruction_code;
|
||||
|
||||
/****************************
|
||||
* Instruction entry point.
|
||||
****************************/
|
||||
|
||||
/**
|
||||
* Describes address of an instruction code.
|
||||
*/
|
||||
typedef struct fcml_st_entry_point {
|
||||
/** Processor operating mode 16/32/64-bit.*/
|
||||
fcml_en_operating_mode op_mode;
|
||||
/** Default address size attribute (See 'D' flag of segment descriptor.)*/
|
||||
fcml_usize address_size_attribute;
|
||||
/** Default operand size attribute (See 'D' flag of segment descriptor.)*/
|
||||
fcml_usize operand_size_attribute;
|
||||
/** Instruction pointer EIP/RIP. Take into account that even in 16 bit
|
||||
* mode EIP register is used.*/
|
||||
fcml_ip ip;
|
||||
} fcml_st_entry_point;
|
||||
|
||||
#endif /* FCML_INT_COMMON_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,660 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_common_utils.h
|
||||
*
|
||||
* Common general purpose utility functions.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2017 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_COMMON_UTILS_H_
|
||||
#define FCML_COMMON_UTILS_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_common.h"
|
||||
#include "fcml_assembler.h"
|
||||
#include "fcml_disassembler.h"
|
||||
#include "fcml_instructions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup REG_STRUCTURES_GROUP Registers
|
||||
* Declarations of structures describing all available registers.
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_AL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_AX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EAX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RAX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM0;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ECX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RCX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM1;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EDX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RDX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM2;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_BL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_BX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EBX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RBX;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM3;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_AH;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_SPL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_SP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ESP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RSP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM4;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CH;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_BPL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_BP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EBP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RBP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM5;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DH;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_SIL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_SI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ESI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RSI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM6;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_BH;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DIL;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EDI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RDI;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_MM7;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM7;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM7;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM7;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R8L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R8W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R8D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R8;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM8;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM8;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM8;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R9L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R9W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R9D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R9;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM9;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM9;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM9;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R10L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R10W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R10D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R10;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM10;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM10;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM10;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R11L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R11W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R11D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R11;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM11;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM11;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM11;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R12L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R12W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R12D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R12;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM12;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM12;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM12;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R13L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R13W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R13D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R13;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM13;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM13;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM13;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R14L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R14W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R14D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R14;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM14;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM14;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM14;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R15L;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R15W;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R15D;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_R15;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM15;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM15;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM15;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM16;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM16;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM16;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM17;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM17;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM17;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM18;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM18;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM18;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM19;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM19;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM19;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM20;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM20;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM20;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM21;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM21;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM21;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM22;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM22;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM22;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM23;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM23;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM23;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM24;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM24;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM24;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM25;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM25;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM25;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM26;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM26;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM26;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM27;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM27;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM27;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM28;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM28;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM28;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM29;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM29;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM29;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM30;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM30;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM30;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_XMM31;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_YMM31;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ZMM31;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ES;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CS;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_SS;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DS;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_FS;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_GS;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_ST7;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CR0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CR2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CR3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CR4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_CR8;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_DR7;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K0;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K1;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K2;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K3;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K4;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K5;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K6;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_K7;
|
||||
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_IP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_EIP;
|
||||
extern LIB_EXPORT fcml_st_register fcml_reg_RIP;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Prepares register operand for given register.
|
||||
* @param reg Register for instruction operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_reg(
|
||||
fcml_st_register *reg);
|
||||
|
||||
/* IMM.*/
|
||||
|
||||
/** Prepares immediate operand for unsigned int8.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_unsigned_imm_8(
|
||||
fcml_uint8_t value);
|
||||
/** Prepares immediate operand for signed int8.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_signed_imm_8(
|
||||
fcml_int8_t value);
|
||||
/** Prepares immediate operand for unsigned int16.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_unsigned_imm_16(
|
||||
fcml_uint16_t value);
|
||||
/** Prepares immediate operand for signed int16.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_signed_imm_16(
|
||||
fcml_int16_t value);
|
||||
/** Prepares immediate operand for unsigned int32.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_unsigned_imm_32(
|
||||
fcml_uint32_t value);
|
||||
/** Prepares immediate operand for signed int32.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_signed_imm_32(
|
||||
fcml_int32_t value);
|
||||
/** Prepares immediate operand for unsigned int64.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_unsigned_imm_64(
|
||||
fcml_uint64_t value);
|
||||
/** Prepares immediate operand for signed int64.
|
||||
* @param value Value for immediate operand.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_signed_imm_64(
|
||||
fcml_int64_t value);
|
||||
|
||||
/* Memory addressing.*/
|
||||
|
||||
/** Prepares far pointer operand for given segment and offset.
|
||||
* @param seg 16-bit code segment.
|
||||
* @param offset 16-bit code offset.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_far_pointer_offset16(
|
||||
fcml_int16_t seg, fcml_int16_t offset);
|
||||
/** Prepares far pointer operand for given segment and offset.
|
||||
* @param seg 16-bit code segment.
|
||||
* @param offset 32-bit code offset.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_far_pointer_offset32(
|
||||
fcml_int16_t seg, fcml_int32_t offset);
|
||||
/** Prepares memory addressing operand for 16-bit absolute offset.
|
||||
* @param offset 16-bit absolute offset.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_offset_16(
|
||||
fcml_int16_t offset, fcml_usize size_operator);
|
||||
/** Prepares memory addressing operand for 32-bit absolute offset.
|
||||
* @param offset 32-bit absolute offset.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_offset_32(
|
||||
fcml_int32_t offset, fcml_usize size_operator);
|
||||
/** Prepares memory addressing operand for 64-bit absolute offset. Function
|
||||
* sets operand level hint: FCML_OP_HINT_ABSOLUTE_ADDRESSING.
|
||||
* @param offset 64-bit absolute offset.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
* @see RIP addressing.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_offset_abs_64(
|
||||
fcml_int64_t offset, fcml_usize size_operator);
|
||||
/** Prepares memory addressing operand for 64-bit absolute offset. Function
|
||||
* sets operand level hint: FCML_OP_HINT_RELATIVE_ADDRESSING.
|
||||
* @param offset 64-bit absolute offset.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
* @see RIP addressing.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_offset_rel_64(
|
||||
fcml_int64_t offset, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 16-bit displacement.
|
||||
* @param disp 16-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_disp_16(
|
||||
fcml_int16_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 32-bit displacement.
|
||||
* @param disp 32-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_disp_32(
|
||||
fcml_int32_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 64-bit displacement.
|
||||
* @param disp 64-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_disp_64(
|
||||
fcml_int64_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 8-bit displacement
|
||||
* and base register.
|
||||
* @param base Base register.
|
||||
* @param disp 8-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_b_disp_8(
|
||||
fcml_st_register *base, fcml_int8_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 16-bit displacement
|
||||
* and base register.
|
||||
* @param base Base register.
|
||||
* @param disp 16-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_b_disp_16(
|
||||
fcml_st_register *base, fcml_int16_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 32-bit displacement
|
||||
* and base register.
|
||||
* @param base Base register.
|
||||
* @param disp 32-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_b_disp_32(
|
||||
fcml_st_register *base, fcml_int32_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 64-bit displacement
|
||||
* and base register.
|
||||
* @param base Base register.
|
||||
* @param disp 64-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_b_disp_64(
|
||||
fcml_st_register *base, fcml_int64_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 8-bit displacement,
|
||||
* scale factor and index register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 8-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_is_disp_8(
|
||||
fcml_st_register *index, fcml_uint8_t scale_factor, fcml_int8_t disp,
|
||||
fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 16-bit displacement,
|
||||
* scale factor and index register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 16-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_is_disp_32(
|
||||
fcml_st_register *index, fcml_uint8_t scale_factor, fcml_int32_t disp,
|
||||
fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 32-bit displacement,
|
||||
* scale factor and index register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 32-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_is_disp_64(
|
||||
fcml_st_register *index, fcml_uint8_t scale_factor, fcml_int64_t disp,
|
||||
fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 8-bit displacement,
|
||||
* base register, scale factor and index register.
|
||||
* @param base Base register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 8-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_bis_disp_8(
|
||||
fcml_st_register *base, fcml_st_register *index,
|
||||
fcml_uint8_t scale_factor, fcml_int8_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 16-bit displacement,
|
||||
* base register, scale factor and index register.
|
||||
* @param base Base register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 16-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_bis_disp_32(
|
||||
fcml_st_register *base, fcml_st_register *index,
|
||||
fcml_uint8_t scale_factor, fcml_int32_t disp, fcml_usize size_operator);
|
||||
/** Prepares effective memory addressing operand for 32-bit displacement,
|
||||
* base register, scale factor and index register.
|
||||
* @param base Base register.
|
||||
* @param index Index register.
|
||||
* @param scale_factor Scale factor.
|
||||
* @param disp 32-bit displacement.
|
||||
* @param size_operator Size operator.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_operand_addr_bis_disp_64(
|
||||
fcml_st_register *base, fcml_st_register *index,
|
||||
fcml_uint8_t scale_factor, fcml_int64_t disp, fcml_usize size_operator);
|
||||
|
||||
/** Adds hints to the operand.
|
||||
* @param operand Operand for hints.
|
||||
* @param hints Hints mask.
|
||||
* @return Prepared operand.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand LIB_CALL fcml_fn_cu_add_operand_hints(
|
||||
fcml_st_operand operand, fcml_hints hints);
|
||||
|
||||
/** Clones given instruction.
|
||||
* Allocates new instance of instruction and makes a deep copy of
|
||||
* all fields. Remember that cloned instructions have to be freed
|
||||
* using fcml_fn_cu_free_instruction() function. Do not try to free
|
||||
* it on your own because it might be allocated on different
|
||||
* dedicated memory heap.
|
||||
* @param instruction Instruction to be cloned.
|
||||
* @return Cloned instruction.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_instruction* LIB_CALL fcml_fn_cu_clone_instruction(
|
||||
fcml_st_instruction *instruction);
|
||||
|
||||
/** Frees given instruction.
|
||||
* Frees instruction allocated by fcml_fn_cu_clone_instruction() function.
|
||||
* @param instruction Instruction to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_cu_free_instruction(
|
||||
fcml_st_instruction *instruction);
|
||||
|
||||
/** Gets operand of given type or NULL if there is no such operand.
|
||||
* If more than one operand of given type exist, the first one is returned.
|
||||
* @param instruction Finds an operand of the given type for for
|
||||
* given instruction.
|
||||
* @param operand_type Operand type.
|
||||
* @return Pointer to the operand of given type.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_operand* fcml_fn_cu_find_operand(
|
||||
fcml_st_instruction *instruction, fcml_en_operand_type operand_type);
|
||||
|
||||
/* Some shortcuts for those who prefer to use macros instead of functions.*/
|
||||
|
||||
#define FCML_IMM8_S( x ) fcml_fn_cu_operand_signed_imm_8( x )
|
||||
#define FCML_IMM8( x ) fcml_fn_cu_operand_unsigned_imm_8( x )
|
||||
#define FCML_IMM16_S( x ) fcml_fn_cu_operand_signed_imm_16( x )
|
||||
#define FCML_IMM16( x ) fcml_fn_cu_operand_unsigned_imm_16( x )
|
||||
#define FCML_IMM32_S( x ) fcml_fn_cu_operand_signed_imm_32( x )
|
||||
#define FCML_IMM32( x ) fcml_fn_cu_operand_unsigned_imm_32( x )
|
||||
#define FCML_IMM64_S( x ) fcml_fn_cu_operand_signed_imm_64( x )
|
||||
#define FCML_IMM64( x ) fcml_fn_cu_operand_unsigned_imm_64( x )
|
||||
|
||||
#ifdef FCML_USE_SHORT_REG
|
||||
#define FCML_REG( x ) fcml_fn_cu_operand_reg( &fcml_reg_##x )
|
||||
#else
|
||||
#define FCML_REG( x ) fcml_fn_cu_operand_reg( &x )
|
||||
#endif
|
||||
|
||||
#define FCML_FAR_POINTER_16( seg, offset ) \
|
||||
fcml_fn_cu_operand_addr_far_pointer_offset16( seg, offset )
|
||||
#define FCML_FAR_POINTER_32( seg, offset ) \
|
||||
fcml_fn_cu_operand_addr_far_pointer_offset32( seg, offset )
|
||||
#define FCML_OFFSET_16( offset ) \
|
||||
fcml_fn_cu_operand_addr_offset_16( offset )
|
||||
#define FCML_OFFSET_32( offset ) \
|
||||
fcml_fn_cu_operand_addr_offset_32( offset )
|
||||
#define FCML_OFFSET_ABS_64( offset ) \
|
||||
fcml_fn_cu_operand_addr_offset_abs_64( offset )
|
||||
#define FCML_OFFSET_REL_64( offset ) \
|
||||
fcml_fn_cu_operand_addr_offset_rel_64( offset )
|
||||
#define FCML_DISP_16( offset ) \
|
||||
fcml_fn_cu_operand_addr_disp_16( offset )
|
||||
#define FCML_DISP_32( offset ) \
|
||||
fcml_fn_cu_operand_addr_disp_32( offset )
|
||||
#define FCML_DISP_64( offset ) \
|
||||
fcml_fn_cu_operand_addr_disp_64( offset )
|
||||
|
||||
#ifdef FCML_USE_SHORT_REG
|
||||
#define FCML_B_DISP_8(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_8( &fcml_reg_##base, offset )
|
||||
#define FCML_B_DISP_16(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_16( &fcml_reg_##base, offset )
|
||||
#define FCML_B_DISP_32(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_32( &fcml_reg_##base, offset )
|
||||
#define FCML_B_DISP_64(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_64( &fcml_reg_##base, offset )
|
||||
#define FCML_IS_DISP_8(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_8( &fcml_reg_##index, scale, offset )
|
||||
#define FCML_IS_DISP_16(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_32( &fcml_reg_##index, scale, offset )
|
||||
#define FCML_IS_DISP_32(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_64( &fcml_reg_##index, scale, offset )
|
||||
#define FCML_BIS_DISP_8(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_8( &fcml_reg_##base, &fcml_reg_##index, \
|
||||
scale, offset )
|
||||
#define FCML_BIS_DISP_16(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_32( &fcml_reg_##base, &fcml_reg_##index, \
|
||||
scale, offset )
|
||||
#define FCML_BIS_DISP_32(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_64( &fcml_reg_##base, &fcml_reg_##index, \
|
||||
scale, offset )
|
||||
#else
|
||||
#define FCML_B_DISP_8(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_8( &base, offset )
|
||||
#define FCML_B_DISP_16(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_16( &base, offset )
|
||||
#define FCML_B_DISP_32(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_32( &base, offset )
|
||||
#define FCML_B_DISP_64(base, offset) \
|
||||
fcml_fn_cu_operand_addr_b_disp_64( &base, offset )
|
||||
#define FCML_IS_DISP_8(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_8( &index, scale, offset )
|
||||
#define FCML_IS_DISP_16(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_32( &index, scale, offset )
|
||||
#define FCML_IS_DISP_32(index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_is_disp_64( &index, scale, offset )
|
||||
#define FCML_BIS_DISP_8(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_8( &base, &index, scale, offset )
|
||||
#define FCML_BIS_DISP_16(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_32( &base, &index, scale, offset )
|
||||
#define FCML_BIS_DISP_32(base, index, scale, offset) \
|
||||
fcml_fn_cu_operand_addr_bis_disp_64( &base, &index, scale, offset )
|
||||
#endif
|
||||
|
||||
#define FCML_IS_INSTRUCTION_GROUP(result, group) \
|
||||
( result.instruction_details.instruction_group & ( group ) )
|
||||
#define FCML_IS_INSTRUCTION_CODE(result, _ins) \
|
||||
( result.instruction_details.instruction == _ins )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_COMMON_UTILS_H_ */
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_dialect.h
|
||||
* Structures and functions related to dialects.
|
||||
* Functions and structures used for developing new dialects are not exposed
|
||||
* as public API. If you are interested in implementing another dialect
|
||||
* you have to use internal headers.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_DIALECT_H_
|
||||
#define FCML_DIALECT_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
/** Assembler dialect.*/
|
||||
typedef struct fcml_st_dialect fcml_st_dialect;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Frees dialect instance.
|
||||
* Frees all resources occupied by the dialect instance.
|
||||
* @param dialect Dialect to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_dialect_free( fcml_st_dialect *dialect );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_DIALECT_H_ */
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_dialect.hpp
|
||||
* C++ wrapper for the base dialect.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_DIALECT_HPP_
|
||||
#define FCML_DIALECT_HPP_
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
|
||||
#include "fcml_dialect.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* An abstract dialect. It's a base class for all supported dialects.
|
||||
* @since 1.1.0
|
||||
* @remarks This class is thread-safe.
|
||||
*/
|
||||
class Dialect: public NonCopyable {
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Dialect() {
|
||||
_dialect = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~Dialect() {
|
||||
if (_dialect) {
|
||||
::fcml_fn_dialect_free(_dialect);
|
||||
_dialect = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class DialectAware;
|
||||
|
||||
/**
|
||||
* Gets the wrapped FCML dialect.
|
||||
*
|
||||
* @return The wrapped FCML dialect.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_st_dialect* getDialect() const {
|
||||
return _dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new dialect for the wrapper.
|
||||
*
|
||||
* @param dialect The new dialect for the wrapper.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setDialect(fcml_st_dialect *dialect) {
|
||||
this->_dialect = dialect;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Wrapped dialect */
|
||||
fcml_st_dialect *_dialect;
|
||||
|
||||
};
|
||||
|
||||
/** Inherit from this class in order to get access to the native FCML
|
||||
* dialect structure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class DialectAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
DialectAware() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~DialectAware() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the native FCML dialect from the dialect object.
|
||||
*
|
||||
* @param dialect The wrapper.
|
||||
* @return The wrapped FCML dialect.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_st_dialect* extractDialect(const Dialect &dialect) const {
|
||||
return dialect.getDialect();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_DIALECT_HPP_ */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_env.h
|
||||
* API for environment configuration.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ENV_H_
|
||||
#define FCML_ENV_H_
|
||||
|
||||
#include "fcml_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Memory allocator handler function pointer declaration.
|
||||
* Memory allocation handlers are used to allocate requested memory in
|
||||
* environment specific way.
|
||||
* @param size Size of the memory to allocate.
|
||||
* @return The allocated memory block or NULL in case of out of memory.
|
||||
*/
|
||||
typedef fcml_ptr (*fcml_fp_env_memory_alloc_handler)(fcml_usize size);
|
||||
|
||||
/** Memory reallocator handler function pointer declaration.
|
||||
* Memory reallocation handlers are used to reallocate requested memory in
|
||||
* environment specific way.
|
||||
* @param ptr The memory block to be reallocated.
|
||||
* @param size Size of the memory to allocate.
|
||||
* @return The reallocated memory block or NULL in case of out of memory.
|
||||
*/
|
||||
typedef fcml_ptr (*fcml_fp_env_memory_realloc_handler)(fcml_ptr ptr,
|
||||
fcml_usize size);
|
||||
|
||||
/** Memory deallocator handler function pointer declaration.
|
||||
* Memory deallocation handlers are used to free requested memory blocks in
|
||||
* environment specific way.
|
||||
* @param memory_block The memory block to free.
|
||||
*/
|
||||
typedef void (*fcml_fp_env_memory_free_handler)(fcml_ptr memory_block);
|
||||
|
||||
/**
|
||||
* Registers the new dedicated handler responsible for allocating
|
||||
* memory for the sake of internal FCML implementation.
|
||||
* @param handler New memory allocation handler.
|
||||
* @return The replaced memory handler.
|
||||
*/
|
||||
LIB_EXPORT fcml_fp_env_memory_alloc_handler LIB_CALL
|
||||
fcml_fn_env_register_memory_alloc_handler(
|
||||
fcml_fp_env_memory_alloc_handler handler);
|
||||
|
||||
/**
|
||||
* Registers the new dedicated handler responsible for reallocating
|
||||
* memory for the sake
|
||||
* of internal FCML implementation.
|
||||
* @param handler New memory reallocation handler.
|
||||
* @return The replaced memory handler.
|
||||
*/
|
||||
LIB_EXPORT fcml_fp_env_memory_realloc_handler LIB_CALL
|
||||
fcml_fn_env_register_memory_realloc_handler(
|
||||
fcml_fp_env_memory_realloc_handler handler);
|
||||
|
||||
/**
|
||||
* Registers the new dedicated handler responsible for deallocating the
|
||||
* memory for the sake
|
||||
* of internal FCML implementation.
|
||||
* @param handler New memory deallocation handler.
|
||||
* @return The replaced memory handler.
|
||||
*/
|
||||
LIB_EXPORT fcml_fp_env_memory_free_handler LIB_CALL
|
||||
fcml_fn_env_register_memory_free_handler(
|
||||
fcml_fp_env_memory_free_handler handler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_ENV_H_ */
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_errors.h
|
||||
* Global error handling related declarations.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ASM_ERRORS_H_
|
||||
#define FCML_ASM_ERRORS_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
|
||||
/**
|
||||
* @defgroup ERRORS_GROUP Global error codes
|
||||
* Describes all available global error codes.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** All global error codes are placed here. */
|
||||
enum fcml_en_ceh_error_globals {
|
||||
/** Operation succeed. */
|
||||
FCML_CEH_GEC_NO_ERROR = 0,
|
||||
/** There is not enough memory to complete operation. */
|
||||
FCML_CEH_GEC_OUT_OF_MEMORY = 1,
|
||||
/** Invalid function arguments. */
|
||||
FCML_CEH_GEC_INVALID_INPUT = 2,
|
||||
/** An internal error occurred. Enable tracing in order to get more
|
||||
* detailed information. */
|
||||
FCML_CEH_GEC_INTERNAL_ERROR = 3,
|
||||
/** Component hasn't been initialized yet. */
|
||||
FCML_CEH_GEC_NOT_INITIALIZED = 4,
|
||||
/** Incomplete instruction. */
|
||||
FCML_CEH_GEC_EOF = 5,
|
||||
/** Used mainly in case of integers and offsets. */
|
||||
FCML_CEH_GEC_VALUE_OUT_OF_RANGE = 6,
|
||||
/** Chosen operation is not supported in case of given configuration. */
|
||||
FCML_CEH_GEC_FEATURE_NOT_SUPPORTED = 7,
|
||||
/** Unsupported operating mode. For instance encoded instruction needs 16
|
||||
* bit operating mode, but we are in 64 bit mode. */
|
||||
FCML_CEH_GEC_INVALID_OPERATING_MODE = 8,
|
||||
/** Chosen addressing form can not be encoded as for example ModR/M field. */
|
||||
FCML_CEH_GEC_INVALID_ADDRESSING_FORM = 9,
|
||||
/** Unsupported instruction form (Instruction may be supported, but not
|
||||
* with given set of operands). */
|
||||
FCML_CEH_GEC_INVALID_INSTRUCTION_FORM = 10,
|
||||
/** Instruction do not support one of the defined operands. */
|
||||
FCML_CEH_GEC_INVALID_OPPERAND = 11,
|
||||
/** Unknown mnemonic. */
|
||||
FCML_CEH_GEC_UNKNOWN_MNEMONIC = 12,
|
||||
/** Operand size (Operand size attribute) is not allowed in given context. */
|
||||
FCML_CEH_GEC_INVALID_OPPERAND_SIZE = 13,
|
||||
/** Address size (Address size attribute) is not allowed in given context. */
|
||||
FCML_CEH_GEC_INVALID_ADDRESS_SIZE = 14,
|
||||
/** User chosen unsupported addressing form */
|
||||
FCML_CEH_GEC_UNKNOWN_INSTRUCTION = 15,
|
||||
/** Assembler can return this error code if there is not allowed prefix
|
||||
* defined for given instruction. */
|
||||
FCML_CEH_GEC_INVALID_PREFIX = 16,
|
||||
/** Wrong register type. */
|
||||
FCML_CEH_GEC_INVALID_REGISTER_TYPE = 17,
|
||||
/** Wrong register. */
|
||||
FCML_CEH_GEC_INVALID_REGISTER = 18,
|
||||
/** Error returned by parsers when there is undefined symbol used. */
|
||||
FCML_CEH_GEC_UNDEFINED_SYMBOL = 19,
|
||||
/** Labels are not supported. */
|
||||
FCML_CEH_GEC_UNSUPPORTED_LABEL_DECLARATION = 20,
|
||||
/** Required operand decorator is missing. */
|
||||
FCML_CEH_GEC_MISSING_DECORATOR = 21,
|
||||
/** Given operand decorator is not supported by operand. */
|
||||
FCML_CEH_GEC_NOT_SUPPORTED_DECORATOR = 22,
|
||||
/** Gap between operands found. */
|
||||
FCML_CEH_GEC_INVALID_INSTRUCTION_MODEL = 23,
|
||||
/* Decorator is invalid. For example wrong register type is used in
|
||||
* opmask decorator. */
|
||||
FCML_CEH_GEC_INVALID_OPERAND_DECORATOR = 24
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup MESSAGE_ERRORS_GROUP Error codes for textual messages
|
||||
* Describes all available error codes dedicated to textual errors.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Error codes dedicated to textual messages.
|
||||
* In some cases they are a bit more detailed than corresponding
|
||||
* global error codes returned in case of errors. Remember that global
|
||||
* error codes also can be used in place of error codes for textual
|
||||
* messages. It is why they use different code ranges.
|
||||
*/
|
||||
enum fcml_en_ceh_message_errors {
|
||||
/** Segment register can not be overridden. */
|
||||
FCML_CEH_MEC_ERROR_ILLEGAL_SEG_REG_OVERRIDE = 1000,
|
||||
/** To many operands passed to parser. */
|
||||
FCML_CEH_MEC_ERROR_TO_MANY_OPERANDS = 1001,
|
||||
/** Unsupported pseudo-op value. */
|
||||
FCML_CEH_MEC_ERROR_INVALID_PSEUDO_OPCODE_VALUE = 1002,
|
||||
/** HLE prefix is not allowed in given context. */
|
||||
FCML_CEH_MEC_ERROR_HLE_PREFIX_NOT_ALLOWED = 1003,
|
||||
/** There is more than one HLE prefix. */
|
||||
FCML_CEH_MEC_ERROR_HLE_MORE_THAN_ONE_PREFIX = 1004,
|
||||
/** Expression attempts to divide by 0 */
|
||||
FCML_CEH_MEC_ERROR_DIVISION_BY_0 = 1005,
|
||||
/** Wrong value type used in given context. For example float used
|
||||
* in place of integer. */
|
||||
FCML_CEH_MEC_ERROR_WRONG_VALUE_FORMAT = 1006,
|
||||
/** Value out of range, for example 32 bit value used as
|
||||
* segment selector. */
|
||||
FCML_CEH_MEC_ERROR_VALUE_OUT_OF_RANGE = 1007,
|
||||
/** Syntax error from parser. */
|
||||
FCML_CEH_MEC_ERROR_INVALID_SYNTAX = 1008,
|
||||
/** Wrong register type used in place of segment register. */
|
||||
FCML_CEH_MEC_ERROR_INVALID_REGISTER_TYPE_SEG = 1009,
|
||||
/** Symbol is already defined in parser's symbol table. */
|
||||
FCML_CEH_MEC_ERROR_SYMBOL_ALREADY_DEFINED = 1010,
|
||||
/** Symbol is undefined. */
|
||||
FCML_CEH_MEC_ERROR_UNDEFINED_SYMBOL = 1011,
|
||||
/** Parsed line exceed maximal allowed length. */
|
||||
FCML_CEH_MEC_ERROR_PARSED_LINE_TOO_LONG = 1012,
|
||||
/** Invalid vector length size. */
|
||||
FCML_CEH_MEC_ERROR_INVALID_VECTOR_LENGTH = 1013
|
||||
};
|
||||
|
||||
/** Codes for textual warnings. */
|
||||
enum fcml_en_ceh_message_warnings {
|
||||
/** Value out of range */
|
||||
FCML_CEH_MEW_WARN_VALUE_OUT_OF_RANGE = 2000,
|
||||
/** Invalid addressing mode. */
|
||||
FCML_CEH_MEW_WARN_INVALID_ADDRESSING_MODE = 2001
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
/** All error codes should be held in variables of this type. */
|
||||
typedef fcml_uint16_t fcml_ceh_error;
|
||||
|
||||
/** Error levels. */
|
||||
typedef enum fcml_en_ceh_error_level {
|
||||
/** Warnings are reported when processing does not need to be stopped. */
|
||||
FCML_EN_CEH_EL_WARN,
|
||||
/** Errors are reported when something more important happened and
|
||||
* processing should be stopped. */
|
||||
FCML_EN_CEH_EL_ERROR
|
||||
} fcml_en_ceh_error_level;
|
||||
|
||||
/** Information about one particular error/warning. */
|
||||
typedef struct fcml_st_ceh_error_info {
|
||||
/** Next error/warning on the list. */
|
||||
struct fcml_st_ceh_error_info *next_error;
|
||||
/** Error message. */
|
||||
fcml_string message;
|
||||
/** Error code */
|
||||
fcml_ceh_error code;
|
||||
/** Error level. */
|
||||
fcml_en_ceh_error_level level;
|
||||
} fcml_st_ceh_error_info;
|
||||
|
||||
/** Container for all collected errors and warnings. */
|
||||
typedef struct fcml_st_ceh_error_container {
|
||||
/** All errors and warnings going here. */
|
||||
fcml_st_ceh_error_info *errors;
|
||||
/** Pointer to the last error/warning on the list. */
|
||||
fcml_st_ceh_error_info *last_error;
|
||||
} fcml_st_ceh_error_container;
|
||||
|
||||
#endif /* FCML_ASM_ERRORS_H_ */
|
@ -0,0 +1,388 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_errors.hpp
|
||||
* C++ wrapper for the FCML errors handling.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ERRORS_HPP_
|
||||
#define FCML_ERRORS_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_common.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* Contains an error message together with error level and error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ErrorInfo {
|
||||
public:
|
||||
|
||||
/** Error level.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
enum ErrorLevel {
|
||||
EL_ERROR,
|
||||
EL_WARN
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorInfo() :
|
||||
_code( FCML_CEH_GEC_NO_ERROR ),
|
||||
_level( EL_ERROR ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an error for given message and optional error code and level.
|
||||
* @param message The error message.
|
||||
* @param code The error code.
|
||||
* @param level The error level.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorInfo( const fcml_cstring &message, fcml_ceh_error code = FCML_CEH_GEC_NO_ERROR, ErrorLevel level = EL_ERROR ) :
|
||||
_message( message ),
|
||||
_code( code ),
|
||||
_level( level ) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets error code.
|
||||
* @return The error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_ceh_error getCode() const {
|
||||
return _code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new error code.
|
||||
* @param code The new error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setCode(fcml_ceh_error code) {
|
||||
_code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets error level.
|
||||
* @return The error level.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorLevel getLevel() const {
|
||||
return _level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets error level.
|
||||
* @param level The error level.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setLevel(ErrorLevel level) {
|
||||
_level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets error message.
|
||||
* @return The error message.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const fcml_cstring& getMessage() const {
|
||||
return _message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets error message.
|
||||
* @param message The error message.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setMessage(const fcml_cstring& message) {
|
||||
_message = message;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Error message. */
|
||||
fcml_cstring _message;
|
||||
/** Error code */
|
||||
fcml_ceh_error _code;
|
||||
/** Error level. */
|
||||
ErrorLevel _level;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps multiple errors into one component.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ErrorContainer {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorContainer() :
|
||||
_isWarn(false),
|
||||
_isError(false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of errors in the container.
|
||||
* @return The number of errors.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_usize getSize() const {
|
||||
return static_cast<fcml_usize>( _errorInfos.size() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an error at given index.
|
||||
* @param index The error index.
|
||||
* @return The error at given index.
|
||||
* @throw BadArgumentException If index is out of bound.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorInfo& operator[]( fcml_usize index ) const {
|
||||
checkVectorAccess( index );
|
||||
return _errorInfos[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an error at given index.
|
||||
* @param index The error index.
|
||||
* @return The error at given index.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorInfo& operator[]( fcml_usize index ) {
|
||||
checkVectorAccess( index );
|
||||
return _errorInfos[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new error into the container.
|
||||
* @param errorInfo The new error to add.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void addErrorInfo( const ErrorInfo &errorInfo ) {
|
||||
_errorInfos.push_back(errorInfo);
|
||||
switch( errorInfo.getLevel() ) {
|
||||
case ErrorInfo::EL_ERROR:
|
||||
_isError = true;
|
||||
break;
|
||||
case ErrorInfo::EL_WARN:
|
||||
_isWarn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is any error in the container.
|
||||
* @return True if there is any error in the container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isError() const {
|
||||
return _isError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is any warning in the container.
|
||||
* @return True if there is any warning in the container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isWarn() const {
|
||||
return _isWarn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets true if there is any error or warning in the container.
|
||||
* @return True if there is any error or warning in the container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isEmpty() const {
|
||||
return _errorInfos.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first error from the container.
|
||||
* @return The first error.
|
||||
* @throw IllegalStateException Container is empty.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorInfo& getFirstError() const {
|
||||
if( isEmpty() ) {
|
||||
throw IllegalStateException( FCML_TEXT( "Container is empty." ) );
|
||||
}
|
||||
return _errorInfos[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first error from the container.
|
||||
* @return The first error.
|
||||
* @throw IllegalStateException Container is empty.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorInfo& getFirstError() {
|
||||
if( isEmpty() ) {
|
||||
throw IllegalStateException( FCML_TEXT( "Container is empty." ) );
|
||||
}
|
||||
return _errorInfos[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first error message from the container.
|
||||
* @return The first error message.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_cstring getFirstErrorMessage() const {
|
||||
fcml_cstring message;
|
||||
try {
|
||||
const ErrorInfo &errorInfo = getFirstError();
|
||||
message = errorInfo.getMessage();
|
||||
} catch( IllegalStateException &exc ) {
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an error message basing on the first error in the container.
|
||||
* @param message A prefix for the destination error message.
|
||||
* @return Error message.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_cstring prepareErrorMessage( const fcml_cstring &message ) const {
|
||||
const fcml_cstring errorMessage = getFirstErrorMessage();
|
||||
if( errorMessage.empty() ) {
|
||||
return message + FCML_TEXT('.');
|
||||
} else {
|
||||
return message + FCML_TEXT(": ") + errorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans all errors and warnings.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void clean() {
|
||||
_errorInfos.clear();
|
||||
_isWarn = false;
|
||||
_isError = false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Checks bounds of the index.
|
||||
* @param index The index to check.
|
||||
* @throw BadArgumentException Index out of bound.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void checkVectorAccess( fcml_usize index ) const {
|
||||
if( index >= _errorInfos.size() ) {
|
||||
throw BadArgumentException( FCML_TEXT( "Index exceeds the allowed number of error info structures." ) );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/** Error messages. */
|
||||
std::vector<ErrorInfo> _errorInfos;
|
||||
/* Sets if there is any warning in the container. */
|
||||
bool _isWarn;
|
||||
/* Sets if there is any error in the container. */
|
||||
bool _isError;
|
||||
};
|
||||
|
||||
/**
|
||||
* Types converter.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ErrorTypeConverter {
|
||||
public:
|
||||
|
||||
static void convert( const fcml_st_ceh_error_container &src, ErrorContainer &dest ) {
|
||||
fcml_st_ceh_error_info *error = src.errors;
|
||||
while( error ) {
|
||||
ErrorInfo::ErrorLevel level = ( error->level == FCML_EN_CEH_EL_ERROR ) ? ErrorInfo::EL_ERROR : ErrorInfo::EL_WARN;
|
||||
dest.addErrorInfo( ErrorInfo( error->message, error->code, level ) );
|
||||
error = error->next_error;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all exceptions that are aware of ErrorContainer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ErrorContainerAwareException: public BaseException {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an error container aware exception instance and sets basic information for it.
|
||||
* @param msg An error message.
|
||||
* @param errorContainer An error container for exception.
|
||||
* @param error An optional FCML error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ErrorContainerAwareException( const fcml_cstring &msg, const ErrorContainer &errorContainer, fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR ) :
|
||||
BaseException( msg, error ), _errorContainer( errorContainer ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to an error container associated with the exception.
|
||||
* @return The error container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorContainer& getErrorContainer() const {
|
||||
return _errorContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new error container for the exception.
|
||||
* @param errorContainer The new error container to be set for the exception.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setErrorContainer(const ErrorContainer& errorContainer) {
|
||||
_errorContainer = errorContainer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** A container for errors. */
|
||||
ErrorContainer _errorContainer;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // FCML_ERRORS_HPP_
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_gas_dialect.h
|
||||
* AT&T dialect implementation.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ASM_DIALECT_GAS_H_
|
||||
#define FCML_ASM_DIALECT_GAS_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_dialect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Disables "SystemV/386 SVR3.2" compatibility for the non-commutative
|
||||
* arithmetic floating point operations with two register operands. */
|
||||
#define FCML_GAS_DIALECT_CF_SYSV_SVR32_INCOMPATIBLE 0x00000001
|
||||
|
||||
/** Default combination of configuration flags. */
|
||||
#define FCML_GAS_DIALECT_CF_DEFAULT 0
|
||||
|
||||
/**
|
||||
* Initializes AT&T dialect.
|
||||
* Prepares new instance of AT&T dialect for given set of configuration flags.
|
||||
* Every dialect has to be freed using fcml_fn_dialect_free() function.
|
||||
*
|
||||
* @param config_flags Configuration flags dedicated to the dialect.
|
||||
* @param[out] dialect Prepared dialect instance.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
* @see fcml_fn_dialect_free
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_dialect_init_gas(
|
||||
fcml_uint32_t config_flags, fcml_st_dialect **dialect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_ASM_DIALECT_GAS_H_ */
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_gas_dialect.hpp
|
||||
* C++ wrapper for the AT&T dialect.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_GAS_DIALECT_HPP_
|
||||
#define FCML_GAS_DIALECT_HPP_
|
||||
|
||||
#include "fcml_dialect.hpp"
|
||||
|
||||
#include "fcml_gas_dialect.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/** Wraps the AT&T dialect.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class GASDialect: public Dialect {
|
||||
public:
|
||||
/**
|
||||
* Creates AT&T dialect.
|
||||
*
|
||||
* @param flags Optional flags.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
GASDialect(fcml_uint32_t flags = FCML_GAS_DIALECT_CF_DEFAULT) {
|
||||
fcml_st_dialect *dialect;
|
||||
fcml_ceh_error error = ::fcml_fn_dialect_init_gas(flags, &dialect);
|
||||
if (error) {
|
||||
throw InitException(
|
||||
FCML_TEXT("Can not initialize the AT&T dialect."), error);
|
||||
}
|
||||
setDialect(dialect);
|
||||
}
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~GASDialect() {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_GAS_DIALECT_HPP_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_intel_dialect.h
|
||||
* Intel dialect implementation.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_ASM_DIALECT_INTEL_H_
|
||||
#define FCML_ASM_DIALECT_INTEL_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_dialect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Default combination of the configuration flags.*/
|
||||
#define FCML_INTEL_DIALECT_CF_DEFAULT 0
|
||||
|
||||
/**
|
||||
* Initializes Intel dialect.
|
||||
* Prepares new instance of Intel dialect for given set of configuration flags.
|
||||
* Every dialect has to be freed using fcml_fn_dialect_free() function.
|
||||
*
|
||||
* @param config_flags Configuration flags dedicated to the dialect.
|
||||
* @param[out] dialect Prepared dialect instance.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
* @see fcml_fn_dialect_free
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_dialect_init_intel(
|
||||
fcml_uint32_t config_flags, fcml_st_dialect **dialect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_ASM_DIALECT_INTEL_H_ */
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_intel_dialect.hpp
|
||||
* C++ wrapper for the Intel dialect.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_INTEL_DIALECT_HPP_
|
||||
#define FCML_INTEL_DIALECT_HPP_
|
||||
|
||||
#include "fcml_dialect.hpp"
|
||||
|
||||
#include "fcml_intel_dialect.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/** Wraps the Intel dialect.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class IntelDialect: public Dialect {
|
||||
public:
|
||||
/**
|
||||
* Creates the Intel dialect.
|
||||
*
|
||||
* @param flags Optional flags.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
IntelDialect(fcml_uint32_t flags = FCML_INTEL_DIALECT_CF_DEFAULT) {
|
||||
fcml_st_dialect *dialect;
|
||||
fcml_ceh_error error = ::fcml_fn_dialect_init_intel(flags, &dialect);
|
||||
if (error) {
|
||||
throw InitException(
|
||||
FCML_TEXT("Can not initialize the Intel dialect."), error);
|
||||
}
|
||||
Dialect::setDialect(dialect);
|
||||
}
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~IntelDialect() {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_INTEL_DIALECT_HPP_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_lag_assembler.h
|
||||
* Experimental multiline load-and-go assembler implementation.
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_LAG_ASSEMBLER_H_
|
||||
#define FCML_LAG_ASSEMBLER_H_
|
||||
|
||||
#include "fcml_symbols.h"
|
||||
#include "fcml_assembler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Result holder for load-and-go assembler. */
|
||||
typedef struct fcml_st_lag_assembler_result {
|
||||
/** Error and warning messages from one-line assembler. */
|
||||
fcml_st_ceh_error_container errors;
|
||||
/** Number of line where assembler failed. */
|
||||
fcml_int error_line;
|
||||
/** Chain of assembled instructions.*/
|
||||
fcml_st_assembled_instruction *instructions;
|
||||
} fcml_st_lag_assembler_result;
|
||||
|
||||
/** Load-and-go assembler runtime context. */
|
||||
typedef struct fcml_st_lag_assembler_context {
|
||||
/** Assembler instance that should be used to assemble instructions. */
|
||||
fcml_st_assembler *assembler;
|
||||
/** Assembler behavior can be configured here.*/
|
||||
fcml_st_assembler_conf configuration;
|
||||
/** Instruction entry point configuration. */
|
||||
fcml_st_entry_point entry_point;
|
||||
/** Symbols table. */
|
||||
fcml_st_symbol_table symbol_table;
|
||||
} fcml_st_lag_assembler_context;
|
||||
|
||||
/**
|
||||
* Multipass load-and-go assembler.
|
||||
* Assembles all instructions given in the NULL terminated source_code
|
||||
* array of strings. Every instruction has to be represented as one string
|
||||
* in the source array. Like every multipass assembler implementation it
|
||||
* passes through the source code multiple times in order to generate optimal
|
||||
* code. Assembler also supports symbols that can be provided using symbol
|
||||
* table available in the context. Context should be initialized the same way
|
||||
* as in case of one line assembler. The only difference here is the symbol
|
||||
* table itself which can be initialized using fcml_fn_symbol_table_alloc()
|
||||
* function. Symbols can be also declared directly in the source code and
|
||||
* accessed through the same symbols table when processing is done (Only if
|
||||
* you provide valid symbol table through the context). Reusable result holder
|
||||
* has to be prepared using fcml_fn_lag_assembler_result_prepare() function.
|
||||
* As long as the context and the result holder are not shared across multiple
|
||||
* calls function is thread safe.
|
||||
*
|
||||
* @param context Assembler context.
|
||||
* @param source_code NULL terminated array of the instructions.
|
||||
* @param result Reusable result holder.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
* @warning This is an experimental implementation and it still needs
|
||||
* some testing.
|
||||
* @see fcml_fn_lag_assembler_result_prepare
|
||||
* @see fcml_fn_symbol_table_alloc
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_lag_assemble(
|
||||
fcml_st_lag_assembler_context *context, const fcml_string *source_code,
|
||||
fcml_st_lag_assembler_result *result);
|
||||
|
||||
/**
|
||||
* Prepares reusable result holder for assembler.
|
||||
* Every instance of fcml_st_lag_assembler_result structure is reusable from
|
||||
* the assembler's point of view, so it has to be prepared in the right way in
|
||||
* order to allow assembler to reuse it correctly. It is up to the library user
|
||||
* to allocate space for the holder itself. This function is only responsible
|
||||
* for cleaning the structure correctly and preparing it for first assembling
|
||||
* process. Notice that assembler has to clean the result holder at the
|
||||
* beginning so you can not pass an uninitialized memory block because it can
|
||||
* even cause a crash due to illegal memory access.
|
||||
*
|
||||
* @param result Result holder instance to be prepared.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_lag_assembler_result_prepare(
|
||||
fcml_st_lag_assembler_result *result);
|
||||
|
||||
/**
|
||||
* Cleans result holder.
|
||||
* Frees all memory blocks allocated by the assembler and held inside the
|
||||
* result holder (Instructions, errors etc.). Notice that result holder itself
|
||||
* is not freed and can be even safety reused after call to this function. In
|
||||
* fact this function is also called internally by assembler in order to clean
|
||||
* result holder before
|
||||
* reusing it.
|
||||
* @param result Result holder to clean.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_lag_assembler_result_free(
|
||||
fcml_st_lag_assembler_result *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_LAG_ASSEMBLER_H_ */
|
@ -0,0 +1,479 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_lag_assembler.hpp
|
||||
* C++ wrapper for the Multi-pass FCML assembler.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_LAG_ASSEMBLER_HPP_
|
||||
#define FCML_LAG_ASSEMBLER_HPP_
|
||||
|
||||
#include "fcml_assembler.hpp"
|
||||
#include "fcml_symbols.hpp"
|
||||
|
||||
#include "fcml_lag_assembler.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/** Assembler result which contains all assembled instructions. */
|
||||
class MultiPassAssemblerResult {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
MultiPassAssemblerResult() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~MultiPassAssemblerResult() {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets error container.
|
||||
*
|
||||
* @return Error container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorContainer& getErrorContainer() const {
|
||||
return _errorContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets number of assembled instructions.
|
||||
* @return Number of assembled instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_usize getSize() const {
|
||||
return static_cast<fcml_usize>(_assembledInstructions.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets one assembled instruction by its index.
|
||||
*
|
||||
* @param index The index of the assembled instruction.
|
||||
* @return One assembled instruction at given index.
|
||||
* @throw BadArgumentException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const AssembledInstruction& operator[](fcml_usize index) const {
|
||||
if (index > _assembledInstructions.size()) {
|
||||
throw BadArgumentException(FCML_TEXT("Array index out of bound."),
|
||||
FCML_CEH_GEC_VALUE_OUT_OF_RANGE);
|
||||
}
|
||||
return _assembledInstructions[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets constant vector of all assembled instructions.
|
||||
*
|
||||
* @return Assembled instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const std::vector<AssembledInstruction>& getAssembledInstructions() const {
|
||||
return _assembledInstructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets iterator which allows to iterate through the whole machine code
|
||||
* byte by byte.
|
||||
*
|
||||
* @return Iterator instance.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
CodeIterator getCodeIterator() {
|
||||
return CodeIterator(_assembledInstructions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the result. Remember not to use the CodeIterator after the
|
||||
* result is cleared up.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void clear() {
|
||||
_errorContainer.clean();
|
||||
_assembledInstructions.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
/** Only the assembler can modify these objects. */
|
||||
friend class MultiPassAssembler;
|
||||
|
||||
/**
|
||||
* Gets vector of all assembled instructions.
|
||||
*
|
||||
* @return Assembled instructions.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
std::vector<AssembledInstruction>& getAssembledInstructions() {
|
||||
return _assembledInstructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new error container for the result.
|
||||
*
|
||||
* @param errorContainer The new error container to be set.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setErrorContainer(const ErrorContainer &errorContainer) {
|
||||
_errorContainer = errorContainer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Errors container. */
|
||||
ErrorContainer _errorContainer;
|
||||
/** Vector of all assembled instructions. */
|
||||
std::vector<AssembledInstruction> _assembledInstructions;
|
||||
|
||||
};
|
||||
|
||||
/** Assembler context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class MultiPassAssemblerContext {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
MultiPassAssemblerContext() :
|
||||
_symbolTable( NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates assembler context for given operating mode and instruction pointer.
|
||||
* @param operatingMode The operating mode.
|
||||
* @param ip The instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
MultiPassAssemblerContext(EntryPoint::OperatingMode operatingMode,
|
||||
fcml_ip ip = 0) :
|
||||
_entryPoint(operatingMode, ip), _symbolTable( NULL) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets constant reference to assembler configuration.
|
||||
*
|
||||
* @return Assembler configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const AssemblerConf& getConfig() const {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference to the assembler configuration.
|
||||
*
|
||||
* @return Assembler configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
AssemblerConf& getConfig() {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new assembler configuration.
|
||||
*
|
||||
* @return Assembler configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setConfig(const AssemblerConf &config) {
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets constant reference to the entry point.
|
||||
*
|
||||
* @return Entry point.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const EntryPoint& getEntryPoint() const {
|
||||
return _entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reference to the entry point.
|
||||
*
|
||||
* @return Entry point.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
EntryPoint& getEntryPoint() {
|
||||
return _entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new entry point.
|
||||
*
|
||||
* @param entryPoint Entry point to be set.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setEntryPoint(const EntryPoint &entryPoint) {
|
||||
_entryPoint = entryPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new instruction pointer.
|
||||
*
|
||||
* @param ip A new instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setIP(fcml_ip ip) {
|
||||
_entryPoint.setIP(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the instruction pointer by given number of bytes.
|
||||
*
|
||||
* @param ip The number of bytes the instruction pointer should
|
||||
* be incremented by.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void incrementIP(fcml_ip ip) {
|
||||
_entryPoint.incrementIP(ip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new processor operating mode for the entry point.
|
||||
*
|
||||
* @param operatingMode The new operating mode.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOperatingMode(EntryPoint::OperatingMode operatingMode) {
|
||||
_entryPoint.setOpMode(operatingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new address size attribute for the entry point.
|
||||
*
|
||||
* @param addressSizeAttribute The address size attribute.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setAddressSizeAttribute(fcml_usize addressSizeAttribute) {
|
||||
_entryPoint.setAddressSizeAttribute(addressSizeAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new operand size attribute for the entry point.
|
||||
*
|
||||
* @param operandSizeAttribute The operand size attribute.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setOperandSizeAttribute(fcml_usize operandSizeAttribute) {
|
||||
_entryPoint.setOperandSizeAttribute(operandSizeAttribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the constant symbol table stored in the context.
|
||||
*
|
||||
* @return The pointer to the symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const SymbolTable* getSymbolTable() const {
|
||||
return _symbolTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the symbol table stored in the context.
|
||||
*
|
||||
* @return The pointer to the symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
SymbolTable* getSymbolTable() {
|
||||
return _symbolTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new symbol table for the context.
|
||||
*
|
||||
* @param symbolTable The new symbol table to be set.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setSymbolTable(SymbolTable *symbolTable) {
|
||||
_symbolTable = symbolTable;
|
||||
}
|
||||
|
||||
private:
|
||||
/** The entry point. */
|
||||
EntryPoint _entryPoint;
|
||||
/** The assembler configuration. */
|
||||
AssemblerConf _config;
|
||||
/** The symbol table assigned to the context. */
|
||||
SymbolTable *_symbolTable;
|
||||
};
|
||||
|
||||
/**
|
||||
* An assembler wrapper, as you can see the assembler context is
|
||||
* managed internally and
|
||||
* is not exposed outside.
|
||||
*/
|
||||
class MultiPassAssembler: public NonCopyable,
|
||||
protected DialectAware,
|
||||
protected SymbolTableAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates multi-pass assembler for a dialect.
|
||||
* @param dialect The dialect for the assembler.
|
||||
* @throw InitException Cannot initialize the assembler.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
MultiPassAssembler(Dialect &dialect) :
|
||||
_dialect(dialect) {
|
||||
fcml_ceh_error error = ::fcml_fn_assembler_init(extractDialect(dialect),
|
||||
&_assembler);
|
||||
if (error) {
|
||||
throw InitException(FCML_TEXT("Cannot initialize the assembler."),
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~MultiPassAssembler() {
|
||||
if (_assembler) {
|
||||
::fcml_fn_assembler_free(_assembler);
|
||||
_assembler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Assembles given instruction model.
|
||||
*
|
||||
* @param ctx Assembler context.
|
||||
* @param instructions A pointer to the NULL terminated array of
|
||||
* the instructions.
|
||||
* @param[out] result Assembler result.
|
||||
* @throw AssemblingFailedException Assembler failed.
|
||||
* @return Error code.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_ceh_error assemble(MultiPassAssemblerContext &ctx,
|
||||
const fcml_string *instructions, MultiPassAssemblerResult &result) {
|
||||
|
||||
/* Prepare assembler context. */
|
||||
fcml_st_lag_assembler_context context = { 0 };
|
||||
|
||||
AssemblerTypeConverter::convert(ctx.getConfig(), context.configuration);
|
||||
TypeConverter::convert(ctx.getEntryPoint(), context.entry_point);
|
||||
|
||||
SymbolTable *symbolTable = ctx.getSymbolTable();
|
||||
context.symbol_table =
|
||||
symbolTable ? extractSymbolTable(*symbolTable) : NULL;
|
||||
context.assembler = _assembler;
|
||||
|
||||
/* Prepare assembler result. */
|
||||
fcml_st_lag_assembler_result res;
|
||||
::fcml_fn_lag_assembler_result_prepare(&res);
|
||||
|
||||
fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR;
|
||||
|
||||
try {
|
||||
|
||||
result.clear();
|
||||
|
||||
error = ::fcml_fn_lag_assemble(&context, instructions, &res);
|
||||
|
||||
/* Failed or not, convert assembler errors. */
|
||||
|
||||
ErrorContainer errorContainer;
|
||||
ErrorTypeConverter::convert(res.errors, errorContainer);
|
||||
|
||||
/* Prepares assembler result. */
|
||||
|
||||
result.setErrorContainer(errorContainer);
|
||||
|
||||
if (error && ctx.getConfig().isThrowExceptionOnError()) {
|
||||
::fcml_fn_lag_assembler_result_free(&res);
|
||||
throw AssemblingFailedException(
|
||||
errorContainer.prepareErrorMessage(
|
||||
FCML_TEXT("Assembling failed")), errorContainer,
|
||||
error);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
|
||||
std::vector<AssembledInstruction> &assembledInstructions =
|
||||
result.getAssembledInstructions();
|
||||
|
||||
assembledInstructions.clear();
|
||||
|
||||
ErrorContainer instructionWarnings;
|
||||
fcml_st_assembled_instruction *next_instruction =
|
||||
res.instructions;
|
||||
while (next_instruction) {
|
||||
fcml_st_ceh_error_container &instruction_warnings =
|
||||
next_instruction->warnings;
|
||||
ErrorTypeConverter::convert(instruction_warnings,
|
||||
instructionWarnings);
|
||||
const AssembledInstruction assembledInstruction(
|
||||
next_instruction->code,
|
||||
next_instruction->code_length, instructionWarnings);
|
||||
assembledInstructions.push_back(assembledInstruction);
|
||||
next_instruction = next_instruction->next;
|
||||
}
|
||||
|
||||
// Convert it back to the context because it might have been
|
||||
// modified during assembling process (IP incrementation etc).
|
||||
TypeConverter::convert(context.entry_point,
|
||||
ctx.getEntryPoint());
|
||||
|
||||
}
|
||||
|
||||
::fcml_fn_lag_assembler_result_free(&res);
|
||||
|
||||
} catch (std::exception &exc) {
|
||||
// If anything failed, free assembler results.
|
||||
::fcml_fn_lag_assembler_result_free(&res);
|
||||
throw exc;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The dialect used by the assembler.
|
||||
Dialect &_dialect;
|
||||
// The initialized assembler instance used by the wrapper.
|
||||
fcml_st_assembler *_assembler;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_LAG_ASSEMBLER_HPP_ */
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_lib_export.h
|
||||
* Handles Win32 DLL symbols importing/exporting.
|
||||
* The only interesting thing here is the LIBFCML_DLL_IMPORT symbol which has to
|
||||
* be always defined in order to use dynamic DLL under Windows. You can achieve it
|
||||
* by declaring the symbol before this header file is included. For example:
|
||||
* @code
|
||||
* #define LIBFCML_DLL_IMPORT
|
||||
* #include <fcml_lib_export.h>
|
||||
* @endcode
|
||||
* Take into account that this header file is included by every FCML public header, so
|
||||
* in fact you should define the symbol before including anything from the FCML library.
|
||||
* This declaration can be omitted as long as you use undecorated symbol names.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2019 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_LIB_EXPORT_H_
|
||||
#define FCML_LIB_EXPORT_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if _WIN32 || __CYGWIN__
|
||||
#define LIB_CALL __stdcall
|
||||
#ifdef DLL_EXPORT
|
||||
#define LIB_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#ifdef LIBFCML_DLL_IMPORT
|
||||
#define LIB_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LIB_EXPORT
|
||||
#define LIB_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef LIB_CALL
|
||||
#define LIB_CALL
|
||||
#endif
|
||||
|
||||
#endif /* FCML_LIB_EXPORT_H_ */
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_optimizers.h
|
||||
* API for assembler optimizers. For more details about optimizers see
|
||||
* FCML manual.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2020 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
#ifndef FCML_OPTIMIZERS_H_
|
||||
#define FCML_OPTIMIZERS_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Optimizer context used as a connector with the environment. */
|
||||
typedef struct fcml_st_asm_optimizer_context {
|
||||
/** Optimizer flags passed through the assembler context.
|
||||
* @see fcml_st_assembler_conf
|
||||
*/
|
||||
fcml_uint16_t optimizer_flags;
|
||||
/** Processor operating mode 16/32/64-bit. */
|
||||
fcml_en_operating_mode op_mode;
|
||||
/** Default address size attribute not modified by prefixes yet.
|
||||
* (See 'D' flag of segment descriptor.)
|
||||
*/
|
||||
fcml_usize asa;
|
||||
/** Default operand size attribute not modified by prefixes yet.
|
||||
* (See 'D' flag of segment descriptor.)
|
||||
*/
|
||||
fcml_usize osa;
|
||||
} fcml_st_asm_optimizer_context;
|
||||
|
||||
/** Processing details for optimizers. */
|
||||
typedef struct fcml_st_asm_optimizer_processing_details {
|
||||
/** Allowed values of the operand size attribute calculated by the
|
||||
* assembler engine.
|
||||
* It is the optimizer who decides which one should be finally used.
|
||||
*/
|
||||
fcml_st_nullable_size_flags allowed_eosa;
|
||||
/** Allowed values of the address size attribute calculated by the
|
||||
* assembler engine.
|
||||
* It is optimizer who decides which one should be finally used.
|
||||
*/
|
||||
fcml_st_nullable_size_flags allowed_easa;
|
||||
/** Effective address size attribute chosen for currently processed
|
||||
* instruction form.
|
||||
* If it is set it can not be changed anymore. It has
|
||||
* higher priority than flags above. Take into account that it is
|
||||
* effective attribute size attribute so it can be forced using instruction
|
||||
* prefixes to override the default attribute size.
|
||||
*/
|
||||
fcml_usize easa;
|
||||
/** Effective operand size attribute chosen for currently processed
|
||||
* instruction form.
|
||||
* If it is set it can not be changed anymore. It has higher priority than
|
||||
* flags above. Take into account that it is effective operand size
|
||||
* attribute so it can be forced using instruction prefixes to override
|
||||
* the default attribute size.
|
||||
*/
|
||||
fcml_usize eosa;
|
||||
/** Vector length of AVX instructions. Set to FCML_DS_UNDEF if not used. */
|
||||
fcml_usize vector_length;
|
||||
/** Set to true in order to break optimization process immediately. */
|
||||
fcml_bool break_optimization;
|
||||
} fcml_st_asm_optimizer_processing_details;
|
||||
|
||||
/**
|
||||
* Callback used to invoke encoding process for given processing details
|
||||
* configuration.
|
||||
* @param args Arguments from optimizer.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*/
|
||||
typedef fcml_ceh_error (*fcml_fnp_asm_optimizer_callback)(fcml_ptr args);
|
||||
|
||||
/**
|
||||
* Function pointer declaration for optimizers.
|
||||
* @param context Optimizer context.
|
||||
* @param ds_flags Current instruction processing details.
|
||||
* @param callback Callback used to continue processing for configuration
|
||||
* prepared by optimizer.
|
||||
* @param args Arguments that should be passed to the callback.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*/
|
||||
typedef fcml_ceh_error (LIB_CALL *fcml_fnp_asm_optimizer)(
|
||||
fcml_st_asm_optimizer_context *context,
|
||||
fcml_st_asm_optimizer_processing_details *ds_flags,
|
||||
fcml_fnp_asm_optimizer_callback callback, fcml_ptr args);
|
||||
|
||||
/* Optimizers flags that can be used to configure optimization process. */
|
||||
#define FCML_OPTF_ASA_16 0x01
|
||||
#define FCML_OPTF_ASA_32 0x02
|
||||
#define FCML_OPTF_ASA_64 0x03
|
||||
#define FCML_OPTF_OSA_16 0x10
|
||||
#define FCML_OPTF_OSA_32 0x20
|
||||
#define FCML_OPTF_OSA_64 0x30
|
||||
/* Do not choose the optimal form, but return all possibilities. */
|
||||
#define FCML_OPTF_ALL_FORMS 0xFF
|
||||
|
||||
/**
|
||||
* Default optimizer implementation.
|
||||
* This implementation chooses the best combination of attributes for
|
||||
* current processor operating mode.
|
||||
* @param context Optimizer context.
|
||||
* @param ds_flags Current instruction processing details.
|
||||
* @param callback Callback used to continue processing for configuration
|
||||
* prepared by optimizer.
|
||||
* @param callback_args Arguments that should be passed to the callback.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_asm_default_optimizer(
|
||||
fcml_st_asm_optimizer_context *context,
|
||||
fcml_st_asm_optimizer_processing_details *ds_flags,
|
||||
fcml_fnp_asm_optimizer_callback callback, fcml_ptr callback_args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_OPTIMIZERS_H_ */
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_parser.h
|
||||
* Structures and functions declarations related to FCML parsers
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_PARSER_H_
|
||||
#define FCML_PARSER_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_common.h"
|
||||
#include "fcml_dialect.h"
|
||||
#include "fcml_symbols.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Maximal number of character for parsed instruction. */
|
||||
#define FCML_PARSER_MAX_INSTRUCTION_LEN 1024
|
||||
|
||||
/** Parser configuration. */
|
||||
typedef struct fcml_st_parser_config {
|
||||
/** Set to true in order to ignore all undefined symbols.
|
||||
* In such a case every unknown symbol is treated as 0.
|
||||
*/
|
||||
fcml_bool ignore_undefined_symbols;
|
||||
/** Disables symbols support.
|
||||
* It set to true every defined label will cause an error.
|
||||
*/
|
||||
fcml_bool disable_symbols_declaration;
|
||||
/** Set to true in order to allow overriding existing labels.
|
||||
* If set to false parser returns "Symbol already exists" error when
|
||||
* symbol already exists.
|
||||
*/
|
||||
fcml_bool override_labels;
|
||||
/** By default parser ignores all symbol declarations
|
||||
* if there is no symbol table provided in the parser
|
||||
* context. By setting this value to true you can force
|
||||
* the parser to allocate new symbol table when needed.
|
||||
* Remember that you are then responsible for freeing it,
|
||||
* so this functionality can be a bit dangerous because
|
||||
* you have to check the existence of the symbol table
|
||||
* every time it should be deallocated.
|
||||
*/
|
||||
fcml_bool alloc_symbol_table_if_needed;
|
||||
// TODO: Support has to be implemented yet.
|
||||
/** Enables textual error messages. */
|
||||
fcml_bool enable_error_messages;
|
||||
} fcml_st_parser_config;
|
||||
|
||||
/** Parser runtime context. */
|
||||
typedef struct fcml_st_parser_context {
|
||||
/** Dialect to be used by parser. Defines supported instructions syntax. */
|
||||
fcml_st_dialect *dialect;
|
||||
/** Parser configuration. */
|
||||
fcml_st_parser_config configuration;
|
||||
/** Instruction pointer. RIP/EIP register value used as a value for
|
||||
* newly declared symbols.
|
||||
* This value is never changed by the parser.
|
||||
*/
|
||||
fcml_ip ip;
|
||||
/** Symbol table. It holds symbols added by the user as
|
||||
* well as symbols allocated by the parsers (labels). It is
|
||||
* very important to free this container on your own
|
||||
* because even if it is not allocated by the user it can be
|
||||
* set by the parser when the first symbol definition is found.
|
||||
* So the most safe way to manage it is to always use
|
||||
* "fcml_fn_symbol_table_free" function as soon as context
|
||||
* if going to be freed.
|
||||
*/
|
||||
fcml_st_symbol_table symbol_table;
|
||||
} fcml_st_parser_context;
|
||||
|
||||
/** Reusable result holder */
|
||||
typedef struct fcml_st_parser_result {
|
||||
/** Parsing errors and warnings going here. */
|
||||
fcml_st_ceh_error_container errors;
|
||||
/** Defined symbol if there is any.
|
||||
* Remember that this symbol is also stored in the context's symbol table.
|
||||
* It is the symbol table that is the owner and that is responsible
|
||||
* for freeing it.
|
||||
*/
|
||||
fcml_st_symbol *symbol;
|
||||
/** Parsed instruction as generic instruction model. */
|
||||
fcml_st_instruction *instruction;
|
||||
} fcml_st_parser_result;
|
||||
|
||||
/**
|
||||
* Parses given instruction into the generic instruction model.
|
||||
* Parses the textual representation of the instruction using dialect and
|
||||
* configuration provided by the parser context. Parsed instruction is returned in the
|
||||
* reusable result holder. Result holder has to be allocated by the
|
||||
* user and appropriately prepared using fcml_fn_parser_result_prepare()
|
||||
* function. As long as the instruction context and the result holder
|
||||
* are not shared across multiple function calls parsing process is
|
||||
* thread safe.
|
||||
*
|
||||
* Remember that textual representation of the instruction has to be written
|
||||
* using syntax supported by the dialect parser is going to use.
|
||||
*
|
||||
* @param context Parser runtime context.
|
||||
* @param instruction textual representation of the instruction to be parsed.
|
||||
* @param result Reusable result holder.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_parse(
|
||||
fcml_st_parser_context *context, const fcml_string instruction,
|
||||
fcml_st_parser_result *result);
|
||||
|
||||
/**
|
||||
* Prepares reusable result holder for parser.
|
||||
* Every instance of fcml_st_parser_result structure is reusable from the
|
||||
* parser's point of view, so it has to be prepared in the right way in order
|
||||
* to allow parser to reuse it correctly. It is up to the library user to
|
||||
* allocate space for the holder itself. This function is only responsible
|
||||
* for cleaning the structure correctly and preparing it for the first parsing
|
||||
* process. Notice that parser has to clean the result holder at the beginning
|
||||
* so you can not pass an uninitialized memory block because it can even cause
|
||||
* a crash due to illegal memory access.
|
||||
*
|
||||
* @param result Result holder instance to be prepared.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_prepare(
|
||||
fcml_st_parser_result *result);
|
||||
|
||||
/**
|
||||
* Cleans result holder.
|
||||
* Frees all memory blocks allocated by the parser and held inside the result
|
||||
* holder (Instructions, errors etc.). Notice that result holder itself is
|
||||
* not freed and can be even safety reused after call to this function. In fact
|
||||
* this function is also called internally by the parser in order to clean
|
||||
* result holder before reusing it.
|
||||
* @param result Result holder to clean.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_parser_result_free(
|
||||
fcml_st_parser_result *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_PARSER_H_ */
|
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_parser.hpp
|
||||
* C++ wrapper for instruction parser.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_PARSER_HPP_
|
||||
#define FCML_PARSER_HPP_
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
#include "fcml_symbols.hpp"
|
||||
#include "fcml_errors.hpp"
|
||||
#include "fcml_dialect.hpp"
|
||||
|
||||
#include "fcml_parser.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* Something failed while parsing.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ParsingFailedException: public ErrorContainerAwareException {
|
||||
public:
|
||||
ParsingFailedException(const fcml_cstring msg,
|
||||
ErrorContainer &errorContainer,
|
||||
fcml_ceh_error error = FCML_CEH_GEC_NO_ERROR) :
|
||||
ErrorContainerAwareException(msg, errorContainer, error) {
|
||||
}
|
||||
};
|
||||
|
||||
/** Parser configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ParserConfig {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserConfig() :
|
||||
_throwExceptionOnError(true),
|
||||
_ignoreUndefinedSymbols(false),
|
||||
_disableSymbolsDeclaration(true),
|
||||
_overrideLabels(false),
|
||||
_allocSymbolTableIfNeeded(false),
|
||||
_enableErrorMessages(true) {
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
bool isAllocSymbolTableIfNeeded() const {
|
||||
return _allocSymbolTableIfNeeded;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setAllocSymbolTableIfNeeded(bool allocSymbolTableIfNeeded) {
|
||||
_allocSymbolTableIfNeeded = allocSymbolTableIfNeeded;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
bool isDisableSymbolsDeclaration() const {
|
||||
return _disableSymbolsDeclaration;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setDisableSymbolsDeclaration(bool disableSymbolsDeclaration) {
|
||||
_disableSymbolsDeclaration = disableSymbolsDeclaration;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
bool isEnableErrorMessages() const {
|
||||
return _enableErrorMessages;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setEnableErrorMessages(bool enableErrorMessages) {
|
||||
_enableErrorMessages = enableErrorMessages;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
bool isIgnoreUndefinedSymbols() const {
|
||||
return _ignoreUndefinedSymbols;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setIgnoreUndefinedSymbols(bool ignoreUndefinedSymbols) {
|
||||
_ignoreUndefinedSymbols = ignoreUndefinedSymbols;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
bool isOverrideLabels() const {
|
||||
return _overrideLabels;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setOverrideLabels(bool overrideLabels) {
|
||||
_overrideLabels = overrideLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets true if exception should be thrown in case of error.
|
||||
* @return True if exception should be thrown in case of error.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isThrowExceptionOnError() const {
|
||||
return _throwExceptionOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets exception on error flag. Has to be set to true if exception
|
||||
* should be thrown in case of error.
|
||||
* @param throwExceptionOnError True if exception should be thrown
|
||||
* in case of error.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setThrowExceptionOnError(bool throwExceptionOnError) {
|
||||
_throwExceptionOnError = throwExceptionOnError;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _throwExceptionOnError;
|
||||
bool _ignoreUndefinedSymbols;
|
||||
bool _disableSymbolsDeclaration;
|
||||
bool _overrideLabels;
|
||||
bool _allocSymbolTableIfNeeded;
|
||||
bool _enableErrorMessages;
|
||||
};
|
||||
|
||||
/** Parser context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ParserContext {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a parser context instance for optional instruction pointer.
|
||||
*
|
||||
* @param ip The instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserContext(fcml_ip ip = 0) :
|
||||
_ip(ip), _symbolTable(NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parser context for given symbol table and optional
|
||||
* instruction pointer.
|
||||
*
|
||||
* @param symbolTable The symbol table.
|
||||
* @param ip The instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserContext(SymbolTable *symbolTable, fcml_ip ip = 0) :
|
||||
_ip(ip), _symbolTable(symbolTable) {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets the parser configuration associated with the context.
|
||||
*
|
||||
* @return The parser configuration associated with the context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ParserConfig& getConfig() const {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parser configuration associated with the context.
|
||||
*
|
||||
* @return The parser configuration associated with the context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserConfig& getConfig() {
|
||||
return _config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction pointer.
|
||||
*
|
||||
* @return The instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_ip getIp() const {
|
||||
return _ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a new instruction pointer.
|
||||
*
|
||||
* @param ip The new instruction pointer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setIp(fcml_ip ip) {
|
||||
_ip = ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments instruction pointer by given number of bytes.
|
||||
*
|
||||
* @param ip The number of bytes the instruction pointer has
|
||||
* to be incremented by.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void incrementIP(fcml_ip ip) {
|
||||
_ip += ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol table associated with the context.
|
||||
*
|
||||
* @return The symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const SymbolTable* getSymbolTable() const {
|
||||
return _symbolTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol table associated with the context.
|
||||
*
|
||||
* @return The symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
SymbolTable* getSymbolTable() {
|
||||
return _symbolTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a symbol table for the instruction.
|
||||
*
|
||||
* @param symbolTable The symbol table for the parser context.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setSymbolTable(SymbolTable *symbolTable) {
|
||||
_symbolTable = symbolTable;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** The instruction pointer used by declared labels. */
|
||||
fcml_ip _ip;
|
||||
/** The parser configuration. */
|
||||
ParserConfig _config;
|
||||
/** The symbol table. */
|
||||
SymbolTable *_symbolTable;
|
||||
|
||||
};
|
||||
|
||||
/** Parser result.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class ParserResult {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an empty parser result.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserResult() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets errors container with parsing errors.
|
||||
*
|
||||
* @return Errors container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const ErrorContainer& getErrors() const {
|
||||
return _errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parsed instruction.
|
||||
*
|
||||
* @return The parsed instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const Instruction& getInstruction() const {
|
||||
return _instruction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets declared symbol is there is any.
|
||||
* @return Gets symbol if there is any.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const Nullable<Symbol>& getSymbol() const {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the parser result.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void clean() {
|
||||
_errors.clean();
|
||||
_symbol.setNotNull(false);
|
||||
_symbol.setValue(Symbol());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class Parser;
|
||||
|
||||
/**
|
||||
* Sets error container for the context.
|
||||
* @param errors A new error container.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setErrors(const ErrorContainer &errors) {
|
||||
_errors = errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an instruction for the container.
|
||||
* @param instruction The instruction.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setInstruction(const Instruction &instruction) {
|
||||
_instruction = instruction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets symbol.
|
||||
* @param symbol The symbol.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setSymbol(const Nullable<Symbol> &symbol) {
|
||||
_symbol = symbol;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Errors container. */
|
||||
ErrorContainer _errors;
|
||||
/** Gets declared symbol. Take into account that it can be 'empty'. */
|
||||
Nullable<Symbol> _symbol;
|
||||
/** The parsed instruction. */
|
||||
Instruction _instruction;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts objects to their structures counterparts.
|
||||
* @since 1.1.0
|
||||
* @remarks Internal API, not intended to be used outside.
|
||||
*/
|
||||
class ParserTypeConverter {
|
||||
public:
|
||||
|
||||
static void convert(ParserConfig &src, fcml_st_parser_config &dest) {
|
||||
dest.alloc_symbol_table_if_needed = src.isAllocSymbolTableIfNeeded();
|
||||
dest.disable_symbols_declaration = src.isDisableSymbolsDeclaration();
|
||||
dest.enable_error_messages = src.isEnableErrorMessages();
|
||||
dest.ignore_undefined_symbols = src.isIgnoreUndefinedSymbols();
|
||||
dest.override_labels = src.isOverrideLabels();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Parser wrapper.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class Parser: protected DialectAware, protected SymbolTableAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a parser instance for the given dialect.
|
||||
*
|
||||
* @param dialect The dialect instance.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Parser(const Dialect &dialect) :
|
||||
_dialect(dialect) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses instruction given in the parameters.
|
||||
*
|
||||
* @param ctx Parser context.
|
||||
* @param instruction Instruction mnemonic.
|
||||
* @param[out] parserResult Instruction result.
|
||||
* @return Error code.
|
||||
* @throw ParsingFailedException Parsing failed.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_ceh_error parse(ParserContext &ctx, const fcml_cstring &instruction,
|
||||
ParserResult &parserResult) {
|
||||
|
||||
// Prepare parser context.
|
||||
fcml_st_parser_context context = { 0 };
|
||||
ParserTypeConverter::convert(ctx.getConfig(), context.configuration);
|
||||
context.ip = ctx.getIp();
|
||||
SymbolTable *symbolTable = ctx.getSymbolTable();
|
||||
context.symbol_table =
|
||||
(symbolTable) ? extractSymbolTable(*symbolTable) : NULL;
|
||||
context.dialect = extractDialect(_dialect);
|
||||
|
||||
fcml_st_parser_result parser_result;
|
||||
::fcml_fn_parser_result_prepare(&parser_result);
|
||||
|
||||
try {
|
||||
|
||||
parserResult.clean();
|
||||
|
||||
// Prepare instruction.
|
||||
fcml_ceh_error error = ::fcml_fn_parse(&context,
|
||||
instruction.c_str(), &parser_result);
|
||||
|
||||
ErrorContainer errorContainer;
|
||||
ErrorTypeConverter::convert(parser_result.errors, errorContainer);
|
||||
|
||||
parserResult.setErrors(errorContainer);
|
||||
|
||||
if (!error && !parser_result.instruction) {
|
||||
// Just in case, it should never happen.
|
||||
error = FCML_CEH_GEC_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (error && ctx.getConfig().isThrowExceptionOnError()) {
|
||||
::fcml_fn_parser_result_free(&parser_result);
|
||||
throw ParsingFailedException(
|
||||
errorContainer.prepareErrorMessage(
|
||||
FCML_TEXT("Parsing failed")), errorContainer,
|
||||
error);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
|
||||
Instruction parsedInstruction;
|
||||
TypeConverter::convert(*(parser_result.instruction),
|
||||
parsedInstruction);
|
||||
|
||||
parserResult.setInstruction(parsedInstruction);
|
||||
parserResult.setSymbol(
|
||||
parser_result.symbol ?
|
||||
Symbol(parser_result.symbol->symbol,
|
||||
parser_result.symbol->value) :
|
||||
Symbol());
|
||||
|
||||
}
|
||||
|
||||
::fcml_fn_parser_result_free(&parser_result);
|
||||
|
||||
} catch (std::exception &exc) {
|
||||
// If anything failed, free assembler results.
|
||||
::fcml_fn_parser_result_free(&parser_result);
|
||||
throw exc;
|
||||
}
|
||||
|
||||
return FCML_CEH_GEC_NO_ERROR;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** The dialect for the parser. */
|
||||
const Dialect &_dialect;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_PARSER_HPP_ */
|
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2015 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_registers.cpp
|
||||
* C++ registers definitions.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
|
||||
#ifndef _FCML_CPP_REGISTERS
|
||||
#define _FCML_CPP_REGISTERS
|
||||
|
||||
#include "fcml_registers.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
const Register UNDEF( 0, 0, Register::REG_UNDEFINED, FCML_FALSE );
|
||||
|
||||
const Register AL( ::fcml_reg_AL );
|
||||
const Register AX( ::fcml_reg_AX );
|
||||
const Register EAX( ::fcml_reg_EAX );
|
||||
const Register RAX( ::fcml_reg_RAX );
|
||||
const Register MM0( ::fcml_reg_MM0 );
|
||||
const Register XMM0( ::fcml_reg_XMM0 );
|
||||
const Register YMM0( ::fcml_reg_YMM0 );
|
||||
const Register ZMM0( ::fcml_reg_ZMM0 );
|
||||
|
||||
const Register CL( ::fcml_reg_CL );
|
||||
const Register CX( ::fcml_reg_CX );
|
||||
const Register ECX( ::fcml_reg_ECX );
|
||||
const Register RCX( ::fcml_reg_RCX );
|
||||
const Register MM1( ::fcml_reg_MM1 );
|
||||
const Register XMM1( ::fcml_reg_XMM1 );
|
||||
const Register YMM1( ::fcml_reg_YMM1 );
|
||||
const Register ZMM1( ::fcml_reg_ZMM1 );
|
||||
|
||||
const Register DL( ::fcml_reg_DL );
|
||||
const Register DX( ::fcml_reg_DX );
|
||||
const Register EDX( ::fcml_reg_EDX );
|
||||
const Register RDX( ::fcml_reg_RDX );
|
||||
const Register MM2( ::fcml_reg_MM2 );
|
||||
const Register XMM2( ::fcml_reg_XMM2 );
|
||||
const Register YMM2( ::fcml_reg_YMM2 );
|
||||
const Register ZMM2( ::fcml_reg_ZMM2 );
|
||||
|
||||
const Register BL( ::fcml_reg_BL );
|
||||
const Register BX( ::fcml_reg_BX );
|
||||
const Register EBX( ::fcml_reg_EBX );
|
||||
const Register RBX( ::fcml_reg_RBX );
|
||||
const Register MM3( ::fcml_reg_MM3 );
|
||||
const Register XMM3( ::fcml_reg_XMM3 );
|
||||
const Register YMM3( ::fcml_reg_YMM3 );
|
||||
const Register ZMM3( ::fcml_reg_ZMM3 );
|
||||
|
||||
const Register AH( ::fcml_reg_AH );
|
||||
const Register SPL( ::fcml_reg_SPL );
|
||||
const Register SP( ::fcml_reg_SP );
|
||||
const Register ESP( ::fcml_reg_ESP );
|
||||
const Register RSP( ::fcml_reg_RSP );
|
||||
const Register MM4( ::fcml_reg_MM4 );
|
||||
const Register XMM4( ::fcml_reg_XMM4 );
|
||||
const Register YMM4( ::fcml_reg_YMM4 );
|
||||
const Register ZMM4( ::fcml_reg_ZMM4 );
|
||||
|
||||
const Register CH( ::fcml_reg_CH );
|
||||
const Register BPL( ::fcml_reg_BPL );
|
||||
const Register BP( ::fcml_reg_BP );
|
||||
const Register EBP( ::fcml_reg_EBP );
|
||||
const Register RBP( ::fcml_reg_RBP );
|
||||
const Register MM5( ::fcml_reg_MM5 );
|
||||
const Register XMM5( ::fcml_reg_XMM5 );
|
||||
const Register YMM5( ::fcml_reg_YMM5 );
|
||||
const Register ZMM5( ::fcml_reg_ZMM5 );
|
||||
|
||||
const Register DH( ::fcml_reg_DH );
|
||||
const Register SIL( ::fcml_reg_SIL );
|
||||
const Register SI( ::fcml_reg_SI );
|
||||
const Register ESI( ::fcml_reg_ESI );
|
||||
const Register RSI( ::fcml_reg_RSI );
|
||||
const Register MM6( ::fcml_reg_MM6 );
|
||||
const Register XMM6( ::fcml_reg_XMM6 );
|
||||
const Register YMM6( ::fcml_reg_YMM6 );
|
||||
const Register ZMM6( ::fcml_reg_ZMM6 );
|
||||
|
||||
const Register BH( ::fcml_reg_BH );
|
||||
const Register DIL( ::fcml_reg_DIL );
|
||||
const Register DI( ::fcml_reg_DI );
|
||||
const Register EDI( ::fcml_reg_EDI );
|
||||
const Register RDI( ::fcml_reg_RDI );
|
||||
const Register MM7( ::fcml_reg_MM7 );
|
||||
const Register XMM7( ::fcml_reg_XMM7 );
|
||||
const Register YMM7( ::fcml_reg_YMM7 );
|
||||
const Register ZMM7( ::fcml_reg_ZMM7 );
|
||||
|
||||
const Register R8L( ::fcml_reg_R8L );
|
||||
const Register R8W( ::fcml_reg_R8W );
|
||||
const Register R8D( ::fcml_reg_R8D );
|
||||
const Register R8( ::fcml_reg_R8 );
|
||||
const Register XMM8( ::fcml_reg_XMM8 );
|
||||
const Register YMM8( ::fcml_reg_YMM8 );
|
||||
const Register ZMM8( ::fcml_reg_ZMM8 );
|
||||
|
||||
const Register R9L( ::fcml_reg_R9L );
|
||||
const Register R9W( ::fcml_reg_R9W );
|
||||
const Register R9D( ::fcml_reg_R9D );
|
||||
const Register R9( ::fcml_reg_R9 );
|
||||
const Register XMM9( ::fcml_reg_XMM9 );
|
||||
const Register YMM9( ::fcml_reg_YMM9 );
|
||||
const Register ZMM9( ::fcml_reg_ZMM9 );
|
||||
|
||||
const Register R10L( ::fcml_reg_R10L );
|
||||
const Register R10W( ::fcml_reg_R10W );
|
||||
const Register R10D( ::fcml_reg_R10D );
|
||||
const Register R10( ::fcml_reg_R10 );
|
||||
const Register XMM10( ::fcml_reg_XMM10 );
|
||||
const Register YMM10( ::fcml_reg_YMM10 );
|
||||
const Register ZMM10( ::fcml_reg_ZMM10 );
|
||||
|
||||
const Register R11L( ::fcml_reg_R11L );
|
||||
const Register R11W( ::fcml_reg_R11W );
|
||||
const Register R11D( ::fcml_reg_R11D );
|
||||
const Register R11( ::fcml_reg_R11 );
|
||||
const Register XMM11( ::fcml_reg_XMM11 );
|
||||
const Register YMM11( ::fcml_reg_YMM11 );
|
||||
const Register ZMM11( ::fcml_reg_ZMM11 );
|
||||
|
||||
const Register R12L( ::fcml_reg_R12L );
|
||||
const Register R12W( ::fcml_reg_R12W );
|
||||
const Register R12D( ::fcml_reg_R12D );
|
||||
const Register R12( ::fcml_reg_R12 );
|
||||
const Register XMM12( ::fcml_reg_XMM12 );
|
||||
const Register YMM12( ::fcml_reg_YMM12 );
|
||||
const Register ZMM12( ::fcml_reg_ZMM12 );
|
||||
|
||||
const Register R13L( ::fcml_reg_R13L );
|
||||
const Register R13W( ::fcml_reg_R13W );
|
||||
const Register R13D( ::fcml_reg_R13D );
|
||||
const Register R13( ::fcml_reg_R13 );
|
||||
const Register XMM13( ::fcml_reg_XMM13 );
|
||||
const Register YMM13( ::fcml_reg_YMM13 );
|
||||
const Register ZMM13( ::fcml_reg_ZMM13 );
|
||||
|
||||
const Register R14L( ::fcml_reg_R14L );
|
||||
const Register R14W( ::fcml_reg_R14W );
|
||||
const Register R14D( ::fcml_reg_R14D );
|
||||
const Register R14( ::fcml_reg_R14 );
|
||||
const Register XMM14( ::fcml_reg_XMM14 );
|
||||
const Register YMM14( ::fcml_reg_YMM14 );
|
||||
const Register ZMM14( ::fcml_reg_ZMM14 );
|
||||
|
||||
const Register R15L( ::fcml_reg_R15L );
|
||||
const Register R15W( ::fcml_reg_R15W );
|
||||
const Register R15D( ::fcml_reg_R15D );
|
||||
const Register R15( ::fcml_reg_R15 );
|
||||
const Register XMM15( ::fcml_reg_XMM15 );
|
||||
const Register YMM15( ::fcml_reg_YMM15 );
|
||||
const Register ZMM15( ::fcml_reg_ZMM15 );
|
||||
|
||||
const Register XMM16( ::fcml_reg_XMM16 );
|
||||
const Register YMM16( ::fcml_reg_YMM16 );
|
||||
const Register ZMM16( ::fcml_reg_ZMM16 );
|
||||
|
||||
const Register XMM17( ::fcml_reg_XMM17 );
|
||||
const Register YMM17( ::fcml_reg_YMM17 );
|
||||
const Register ZMM17( ::fcml_reg_ZMM17 );
|
||||
|
||||
const Register XMM18( ::fcml_reg_XMM18 );
|
||||
const Register YMM18( ::fcml_reg_YMM18 );
|
||||
const Register ZMM18( ::fcml_reg_ZMM18 );
|
||||
|
||||
const Register XMM19( ::fcml_reg_XMM19 );
|
||||
const Register YMM19( ::fcml_reg_YMM19 );
|
||||
const Register ZMM19( ::fcml_reg_ZMM19 );
|
||||
|
||||
const Register XMM20( ::fcml_reg_XMM20 );
|
||||
const Register YMM20( ::fcml_reg_YMM20 );
|
||||
const Register ZMM20( ::fcml_reg_ZMM20 );
|
||||
|
||||
const Register XMM21( ::fcml_reg_XMM21 );
|
||||
const Register YMM21( ::fcml_reg_YMM21 );
|
||||
const Register ZMM21( ::fcml_reg_ZMM21 );
|
||||
|
||||
const Register XMM22( ::fcml_reg_XMM22 );
|
||||
const Register YMM22( ::fcml_reg_YMM22 );
|
||||
const Register ZMM22( ::fcml_reg_ZMM22 );
|
||||
|
||||
const Register XMM23( ::fcml_reg_XMM23 );
|
||||
const Register YMM23( ::fcml_reg_YMM23 );
|
||||
const Register ZMM23( ::fcml_reg_ZMM23 );
|
||||
|
||||
const Register XMM24( ::fcml_reg_XMM24 );
|
||||
const Register YMM24( ::fcml_reg_YMM24 );
|
||||
const Register ZMM24( ::fcml_reg_ZMM24 );
|
||||
|
||||
const Register XMM25( ::fcml_reg_XMM25 );
|
||||
const Register YMM25( ::fcml_reg_YMM25 );
|
||||
const Register ZMM25( ::fcml_reg_ZMM25 );
|
||||
|
||||
const Register XMM26( ::fcml_reg_XMM26 );
|
||||
const Register YMM26( ::fcml_reg_YMM26 );
|
||||
const Register ZMM26( ::fcml_reg_ZMM26 );
|
||||
|
||||
const Register XMM27( ::fcml_reg_XMM27 );
|
||||
const Register YMM27( ::fcml_reg_YMM27 );
|
||||
const Register ZMM27( ::fcml_reg_ZMM27 );
|
||||
|
||||
const Register XMM28( ::fcml_reg_XMM28 );
|
||||
const Register YMM28( ::fcml_reg_YMM28 );
|
||||
const Register ZMM28( ::fcml_reg_ZMM28 );
|
||||
|
||||
const Register XMM29( ::fcml_reg_XMM29 );
|
||||
const Register YMM29( ::fcml_reg_YMM29 );
|
||||
const Register ZMM29( ::fcml_reg_ZMM29 );
|
||||
|
||||
const Register XMM30( ::fcml_reg_XMM30 );
|
||||
const Register YMM30( ::fcml_reg_YMM30 );
|
||||
const Register ZMM30( ::fcml_reg_ZMM30 );
|
||||
|
||||
const Register XMM31( ::fcml_reg_XMM31 );
|
||||
const Register YMM31( ::fcml_reg_YMM31 );
|
||||
const Register ZMM31( ::fcml_reg_ZMM31 );
|
||||
|
||||
const Register ES( ::fcml_reg_ES );
|
||||
const Register CS( ::fcml_reg_CS );
|
||||
const Register SS( ::fcml_reg_SS );
|
||||
const Register DS( ::fcml_reg_DS );
|
||||
const Register FS( ::fcml_reg_FS );
|
||||
const Register GS( ::fcml_reg_GS );
|
||||
|
||||
const Register ST0( ::fcml_reg_ST0 );
|
||||
const Register ST1( ::fcml_reg_ST1 );
|
||||
const Register ST2( ::fcml_reg_ST2 );
|
||||
const Register ST3( ::fcml_reg_ST3 );
|
||||
const Register ST4( ::fcml_reg_ST4 );
|
||||
const Register ST5( ::fcml_reg_ST5 );
|
||||
const Register ST6( ::fcml_reg_ST6 );
|
||||
const Register ST7( ::fcml_reg_ST7 );
|
||||
|
||||
const Register CR0( ::fcml_reg_CR0 );
|
||||
const Register CR2( ::fcml_reg_CR2 );
|
||||
const Register CR3( ::fcml_reg_CR3 );
|
||||
const Register CR4( ::fcml_reg_CR4 );
|
||||
const Register CR8( ::fcml_reg_CR8 );
|
||||
|
||||
const Register DR0( ::fcml_reg_DR0 );
|
||||
const Register DR1( ::fcml_reg_DR1 );
|
||||
const Register DR2( ::fcml_reg_DR2 );
|
||||
const Register DR3( ::fcml_reg_DR3 );
|
||||
const Register DR4( ::fcml_reg_DR4 );
|
||||
const Register DR5( ::fcml_reg_DR5 );
|
||||
const Register DR6( ::fcml_reg_DR6 );
|
||||
const Register DR7( ::fcml_reg_DR7 );
|
||||
|
||||
const Register K0( ::fcml_reg_K0 );
|
||||
const Register K1( ::fcml_reg_K1 );
|
||||
const Register K2( ::fcml_reg_K2 );
|
||||
const Register K3( ::fcml_reg_K3 );
|
||||
const Register K4( ::fcml_reg_K4 );
|
||||
const Register K5( ::fcml_reg_K5 );
|
||||
const Register K6( ::fcml_reg_K6 );
|
||||
const Register K7( ::fcml_reg_K7 );
|
||||
|
||||
const Register IP( ::fcml_reg_IP );
|
||||
const Register EIP( ::fcml_reg_EIP );
|
||||
const Register RIP( ::fcml_reg_RIP );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_registers.hpp
|
||||
* C++ registers declarations.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
|
||||
#ifndef FCML_REGISTERS_HPP_
|
||||
#define FCML_REGISTERS_HPP_
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
extern const Register UNDEF;
|
||||
|
||||
extern const Register AL;
|
||||
extern const Register AX;
|
||||
extern const Register EAX;
|
||||
extern const Register RAX;
|
||||
extern const Register MM0;
|
||||
extern const Register XMM0;
|
||||
extern const Register YMM0;
|
||||
extern const Register ZMM0;
|
||||
|
||||
extern const Register CL;
|
||||
extern const Register CX;
|
||||
extern const Register ECX;
|
||||
extern const Register RCX;
|
||||
extern const Register MM1;
|
||||
extern const Register XMM1;
|
||||
extern const Register YMM1;
|
||||
extern const Register ZMM1;
|
||||
|
||||
extern const Register DL;
|
||||
extern const Register DX;
|
||||
extern const Register EDX;
|
||||
extern const Register RDX;
|
||||
extern const Register MM2;
|
||||
extern const Register XMM2;
|
||||
extern const Register YMM2;
|
||||
extern const Register ZMM2;
|
||||
|
||||
extern const Register BL;
|
||||
extern const Register BX;
|
||||
extern const Register EBX;
|
||||
extern const Register RBX;
|
||||
extern const Register MM3;
|
||||
extern const Register XMM3;
|
||||
extern const Register YMM3;
|
||||
extern const Register ZMM3;
|
||||
|
||||
extern const Register AH;
|
||||
extern const Register SPL;
|
||||
extern const Register SP;
|
||||
extern const Register ESP;
|
||||
extern const Register RSP;
|
||||
extern const Register MM4;
|
||||
extern const Register XMM4;
|
||||
extern const Register YMM4;
|
||||
extern const Register ZMM4;
|
||||
|
||||
extern const Register CH;
|
||||
extern const Register BPL;
|
||||
extern const Register BP;
|
||||
extern const Register EBP;
|
||||
extern const Register RBP;
|
||||
extern const Register MM5;
|
||||
extern const Register XMM5;
|
||||
extern const Register YMM5;
|
||||
extern const Register ZMM5;
|
||||
|
||||
extern const Register DH;
|
||||
extern const Register SIL;
|
||||
extern const Register SI;
|
||||
extern const Register ESI;
|
||||
extern const Register RSI;
|
||||
extern const Register MM6;
|
||||
extern const Register XMM6;
|
||||
extern const Register YMM5;
|
||||
extern const Register ZMM5;
|
||||
|
||||
extern const Register BH;
|
||||
extern const Register DIL;
|
||||
extern const Register DI;
|
||||
extern const Register EDI;
|
||||
extern const Register RDI;
|
||||
extern const Register MM7;
|
||||
extern const Register XMM7;
|
||||
extern const Register YMM7;
|
||||
extern const Register ZMM7;
|
||||
|
||||
extern const Register R8L;
|
||||
extern const Register R8W;
|
||||
extern const Register R8D;
|
||||
extern const Register R8;
|
||||
extern const Register XMM8;
|
||||
extern const Register YMM8;
|
||||
extern const Register ZMM8;
|
||||
|
||||
extern const Register R9L;
|
||||
extern const Register R9W;
|
||||
extern const Register R9D;
|
||||
extern const Register R9;
|
||||
extern const Register XMM9;
|
||||
extern const Register YMM9;
|
||||
extern const Register ZMM9;
|
||||
|
||||
extern const Register R10L;
|
||||
extern const Register R10W;
|
||||
extern const Register R10D;
|
||||
extern const Register R10;
|
||||
extern const Register XMM10;
|
||||
extern const Register YMM10;
|
||||
extern const Register ZMM10;
|
||||
|
||||
extern const Register R11L;
|
||||
extern const Register R11W;
|
||||
extern const Register R11D;
|
||||
extern const Register R11;
|
||||
extern const Register XMM11;
|
||||
extern const Register YMM10;
|
||||
extern const Register ZMM10;
|
||||
|
||||
extern const Register R12L;
|
||||
extern const Register R12W;
|
||||
extern const Register R12D;
|
||||
extern const Register R12;
|
||||
extern const Register XMM12;
|
||||
extern const Register YMM12;
|
||||
extern const Register ZMM12;
|
||||
|
||||
extern const Register R13L;
|
||||
extern const Register R13W;
|
||||
extern const Register R13D;
|
||||
extern const Register R13;
|
||||
extern const Register XMM13;
|
||||
extern const Register YMM13;
|
||||
extern const Register ZMM13;
|
||||
|
||||
extern const Register R14L;
|
||||
extern const Register R14W;
|
||||
extern const Register R14D;
|
||||
extern const Register R14;
|
||||
extern const Register XMM14;
|
||||
extern const Register YMM14;
|
||||
extern const Register ZMM14;
|
||||
|
||||
extern const Register R15L;
|
||||
extern const Register R15W;
|
||||
extern const Register R15D;
|
||||
extern const Register R15;
|
||||
extern const Register XMM15;
|
||||
extern const Register YMM15;
|
||||
extern const Register ZMM15;
|
||||
|
||||
extern const Register XMM16;
|
||||
extern const Register YMM16;
|
||||
extern const Register ZMM16;
|
||||
|
||||
extern const Register XMM17;
|
||||
extern const Register YMM17;
|
||||
extern const Register ZMM17;
|
||||
|
||||
extern const Register XMM18;
|
||||
extern const Register YMM18;
|
||||
extern const Register ZMM18;
|
||||
|
||||
extern const Register XMM19;
|
||||
extern const Register YMM19;
|
||||
extern const Register ZMM19;
|
||||
|
||||
extern const Register XMM20;
|
||||
extern const Register YMM20;
|
||||
extern const Register ZMM20;
|
||||
|
||||
extern const Register XMM21;
|
||||
extern const Register YMM21;
|
||||
extern const Register ZMM21;
|
||||
|
||||
extern const Register XMM22;
|
||||
extern const Register YMM22;
|
||||
extern const Register ZMM22;
|
||||
|
||||
extern const Register XMM23;
|
||||
extern const Register YMM23;
|
||||
extern const Register ZMM23;
|
||||
|
||||
extern const Register XMM24;
|
||||
extern const Register YMM24;
|
||||
extern const Register ZMM24;
|
||||
|
||||
extern const Register XMM25;
|
||||
extern const Register YMM25;
|
||||
extern const Register ZMM25;
|
||||
|
||||
extern const Register XMM26;
|
||||
extern const Register YMM26;
|
||||
extern const Register ZMM26;
|
||||
|
||||
extern const Register XMM27;
|
||||
extern const Register YMM27;
|
||||
extern const Register ZMM27;
|
||||
|
||||
extern const Register XMM28;
|
||||
extern const Register YMM28;
|
||||
extern const Register ZMM28;
|
||||
|
||||
extern const Register XMM29;
|
||||
extern const Register YMM29;
|
||||
extern const Register ZMM29;
|
||||
|
||||
extern const Register XMM30;
|
||||
extern const Register YMM30;
|
||||
extern const Register ZMM30;
|
||||
|
||||
extern const Register XMM31;
|
||||
extern const Register YMM31;
|
||||
extern const Register ZMM31;
|
||||
|
||||
extern const Register ES;
|
||||
extern const Register CS;
|
||||
extern const Register SS;
|
||||
extern const Register DS;
|
||||
extern const Register FS;
|
||||
extern const Register GS;
|
||||
|
||||
extern const Register ST0;
|
||||
extern const Register ST1;
|
||||
extern const Register ST2;
|
||||
extern const Register ST3;
|
||||
extern const Register ST4;
|
||||
extern const Register ST5;
|
||||
extern const Register ST6;
|
||||
extern const Register ST7;
|
||||
|
||||
extern const Register CR0;
|
||||
extern const Register CR2;
|
||||
extern const Register CR3;
|
||||
extern const Register CR4;
|
||||
extern const Register CR8;
|
||||
|
||||
extern const Register DR0;
|
||||
extern const Register DR1;
|
||||
extern const Register DR2;
|
||||
extern const Register DR3;
|
||||
extern const Register DR4;
|
||||
extern const Register DR5;
|
||||
extern const Register DR6;
|
||||
extern const Register DR7;
|
||||
|
||||
extern const Register K0;
|
||||
extern const Register K1;
|
||||
extern const Register K2;
|
||||
extern const Register K3;
|
||||
extern const Register K4;
|
||||
extern const Register K5;
|
||||
extern const Register K6;
|
||||
extern const Register K7;
|
||||
|
||||
extern const Register IP;
|
||||
extern const Register EIP;
|
||||
extern const Register RIP;
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_REGISTERS_HPP_ */
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_renderer.h
|
||||
* Structures and functions declarations related to FCML renderers
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_REND_H_
|
||||
#define FCML_REND_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
#include "fcml_types.h"
|
||||
#include "fcml_errors.h"
|
||||
#include "fcml_dialect.h"
|
||||
#include "fcml_disassembler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** The rendered instruction size can not exceed this value. */
|
||||
#define FCML_REND_MAX_BUFF_LEN 512
|
||||
|
||||
/**
|
||||
* @defgroup RENDERER_FLAGS_GROUP Flags configuring rendering process.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Render the instruction code as HEX string. */
|
||||
#define FCML_REND_FLAG_RENDER_CODE 0x00000001
|
||||
/** Render the immediate operand as HEX integer. */
|
||||
#define FCML_REND_FLAG_HEX_IMM 0x00000002
|
||||
/** Render the segment code register even if it is a default one. */
|
||||
#define FCML_REND_FLAG_RENDER_DEFAULT_SEG 0x00000004
|
||||
/** Render the displacement value as HEX integer. */
|
||||
#define FCML_REND_FLAG_HEX_DISPLACEMENT 0x00000008
|
||||
/** Render the conditional mnemonics using suffixes from first group. */
|
||||
#define FCML_REND_FLAG_COND_GROUP_1 0x00000010
|
||||
/** Render the conditional mnemonics using suffixes from second group. */
|
||||
#define FCML_REND_FLAG_COND_GROUP_2 0x00000020
|
||||
/** Render the conditional mnemonics using suffixes for 'carry'. */
|
||||
#define FCML_REND_FLAG_COND_SHOW_CARRY 0x00000040
|
||||
/** Render SIB operand hints. */
|
||||
#define FCML_REND_FLAG_RENDER_SIB_HINT 0x00000080
|
||||
/** Render ABS (Absolute offset) operand hints. */
|
||||
#define FCML_REND_FLAG_RENDER_ABS_HINT 0x00000100
|
||||
/** Render REL (Relative offset) operand hints. */
|
||||
#define FCML_REND_FLAG_RENDER_REL_HINT 0x00000200
|
||||
/** Render hints for absolute addressing. */
|
||||
#define FCML_REND_FLAG_RENDER_INDIRECT_HINT 0x00000400
|
||||
/** Renders repetition prefixes using the first group (repe,repne). */
|
||||
#define FCML_REND_FLAG_REP_PREFIX_GROUP_1 0x00000800
|
||||
/** Renders repetition prefixes using the second group (repz,repnz). */
|
||||
#define FCML_REND_FLAG_REP_PREFIX_GROUP_2 0x00001000
|
||||
/** Renders the code padding between the instruction code and the mnemonic. */
|
||||
#define FCML_REND_FLAG_CODE_PADDING 0x00002000
|
||||
/** Renders the mnemonic padding between the mnemonic and the operands. */
|
||||
#define FCML_REND_FLAG_MNEMONIC_PADDING 0x00004000
|
||||
/** Should be used only with FCML_REND_FLAG_HEX_IMM and FCML_REND_FLAG_
|
||||
* HEX_DISPLACEMENT flags. */
|
||||
#define FCML_REND_FLAG_REMOVE_LEADING_ZEROS 0x00008000
|
||||
|
||||
/** Default set of the rendering flags. */
|
||||
#define FCML_REND_DEFAULT_FLAGS 0
|
||||
/** Default number of characters used as code padding. */
|
||||
#define FCML_REND_DEFAULT_CODE_PADDING 8
|
||||
/** Default number of characters used as mnemonic padding. */
|
||||
#define FCML_REND_DEFAULT_MNEMONIC_PADDING 8
|
||||
|
||||
/** @} */
|
||||
|
||||
/** Renderer configuration. */
|
||||
typedef struct fcml_st_render_config {
|
||||
/** Flags which allows to control rendering process. */
|
||||
fcml_uint32_t render_flags;
|
||||
/** Preferred mnemonic padding in characters. */
|
||||
fcml_uint16_t prefered_mnemonic_padding;
|
||||
/** Preferred code padding in HEX bytes (2 characters on one byte.). */
|
||||
fcml_uint16_t prefered_code_padding;
|
||||
} fcml_st_render_config;
|
||||
|
||||
/**
|
||||
* Renders the disassembled instruction into its textual representation.
|
||||
* Prepares textual representation of the disassembled code using syntax
|
||||
* based on the provided dialect.
|
||||
*
|
||||
* @param dialect Dialect instance.
|
||||
* @param config Renderer configuration.
|
||||
* @param[out] buffer Destination buffer for the generated instruction.
|
||||
* @param buffer_len Size of the destination buffer.
|
||||
* @param result Disassembled instruction.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_render(
|
||||
const fcml_st_dialect *dialect, const fcml_st_render_config *config,
|
||||
fcml_char *buffer, fcml_usize buffer_len,
|
||||
const fcml_st_disassembler_result *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_REND_H_ */
|
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_renderer.hpp
|
||||
* C++ wrapper for FCML renderer.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_RENDERER_HPP_
|
||||
#define FCML_RENDERER_HPP_
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
#include "fcml_disassembler.hpp"
|
||||
#include "fcml_renderer.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* Component can not be initialized correctly.
|
||||
*/
|
||||
class RenderingFailedException: public BaseException {
|
||||
public:
|
||||
RenderingFailedException(const fcml_cstring &msg, fcml_ceh_error error =
|
||||
FCML_CEH_GEC_NO_ERROR) :
|
||||
BaseException(msg, error) {
|
||||
}
|
||||
};
|
||||
|
||||
/** Renderer configuration.
|
||||
*
|
||||
* It's a counterpart to the fcml_st_render_config structure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class RenderConfig {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an empty renderer configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
RenderConfig() :
|
||||
_throwExceptionOnError(true),
|
||||
_renderFlags(0),
|
||||
_preferedMnemonicPadding(FCML_REND_DEFAULT_MNEMONIC_PADDING),
|
||||
_preferedCodePadding(FCML_REND_DEFAULT_CODE_PADDING) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a renderer configuration for given renderer flags.
|
||||
*
|
||||
* @param renderFlags The renderer flags.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
RenderConfig(fcml_uint32_t renderFlags) :
|
||||
_throwExceptionOnError(true),
|
||||
_renderFlags(renderFlags),
|
||||
_preferedMnemonicPadding(0),
|
||||
_preferedCodePadding(0) {
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
fcml_uint16_t getPreferedCodePadding() const {
|
||||
return _preferedCodePadding;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setPreferedCodePadding(fcml_uint16_t preferedCodePadding) {
|
||||
_preferedCodePadding = preferedCodePadding;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
fcml_uint16_t getPreferedMnemonicPadding() const {
|
||||
return _preferedMnemonicPadding;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setPreferedMnemonicPadding(fcml_uint16_t preferedMnemonicPadding) {
|
||||
_preferedMnemonicPadding = preferedMnemonicPadding;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
fcml_uint32_t getRenderFlags() const {
|
||||
return _renderFlags;
|
||||
}
|
||||
|
||||
/** @since 1.1.0 */
|
||||
void setRenderFlags(fcml_uint32_t renderFlags) {
|
||||
_renderFlags = renderFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if exception should be thrown when disassembling fails.
|
||||
*
|
||||
* @return True if exception is the preferred way of error handling
|
||||
* in case of failure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isThrowExceptionOnError() const {
|
||||
return _throwExceptionOnError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the way how the error handling is done.
|
||||
*
|
||||
* @param throwExceptionOnError True if exception should be thrown
|
||||
* in case of failure.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setThrowExceptionOnError(bool throwExceptionOnError) {
|
||||
_throwExceptionOnError = throwExceptionOnError;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** Throws exception in case of error. */
|
||||
bool _throwExceptionOnError;
|
||||
/** Flags which allows to control rendering process. */
|
||||
fcml_uint32_t _renderFlags;
|
||||
/** Preferred mnemonic padding in characters. */
|
||||
fcml_uint16_t _preferedMnemonicPadding;
|
||||
/** Preferred code padding in HEX bytes (2 characters on one byte.). */
|
||||
fcml_uint16_t _preferedCodePadding;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts objects to their structures counterparts.
|
||||
* @since 1.1.0
|
||||
* @remarks Internal API, not intended to be used outside.
|
||||
*/
|
||||
class RenderTypeConverter {
|
||||
public:
|
||||
|
||||
static void convert(const RenderConfig &src, fcml_st_render_config &dest) {
|
||||
dest.prefered_code_padding = src.getPreferedCodePadding();
|
||||
dest.prefered_mnemonic_padding = src.getPreferedMnemonicPadding();
|
||||
dest.render_flags = src.getRenderFlags();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Renderer wrapper.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class Renderer: protected DialectAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a renderer instance for the given dialect.
|
||||
*
|
||||
* @param dialect The dialect instance.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Renderer(Dialect &dialect) :
|
||||
_dialect(dialect) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a disassembled instruction.
|
||||
*
|
||||
* @param renderConfig A renderer configuration.
|
||||
* @param assemblerResult The disassembler result.
|
||||
* @param[out] result The rendered instruction.
|
||||
* @throw RenderingFailedException Rendering failed.
|
||||
* @return The error code.
|
||||
*/
|
||||
fcml_ceh_error render(const RenderConfig &renderConfig,
|
||||
DisassemblerResult &assemblerResult, fcml_cstring &result) {
|
||||
|
||||
result.clear();
|
||||
|
||||
fcml_st_render_config render_config;
|
||||
RenderTypeConverter::convert(renderConfig, render_config);
|
||||
|
||||
fcml_st_disassembler_result disassembler_result;
|
||||
fcml_fn_disassembler_result_prepare(&disassembler_result);
|
||||
|
||||
DisassemblerTypeConverter::convert(assemblerResult,
|
||||
disassembler_result);
|
||||
|
||||
fcml_char buffer[FCML_REND_MAX_BUFF_LEN];
|
||||
|
||||
fcml_ceh_error error = ::fcml_fn_render(extractDialect(_dialect),
|
||||
&render_config, buffer, FCML_REND_MAX_BUFF_LEN,
|
||||
&disassembler_result);
|
||||
|
||||
DisassemblerTypeConverter::free(disassembler_result);
|
||||
|
||||
if (error && renderConfig.isThrowExceptionOnError()) {
|
||||
throw RenderingFailedException(
|
||||
FCML_TEXT("Can not render instruction."), error);
|
||||
}
|
||||
|
||||
result = buffer;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** The dialect instance associated with the renderer. */
|
||||
Dialect &_dialect;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_RENDERER_HPP_ */
|
@ -0,0 +1,554 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_stateful_assembler.hpp
|
||||
* Stateful FCML assembler implementation.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_STATEFUL_ASSEMBLER_HPP_
|
||||
#define FCML_STATEFUL_ASSEMBLER_HPP_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "fcml_assembler.hpp"
|
||||
#include "fcml_parser.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* It's a stateful assembler which can be used to assemble instructions one by
|
||||
* one on the fly. By default is works with the general instruction models as
|
||||
* well as with instruction builders, but it can be also configured to parse
|
||||
* whole statements using internally managed parser. It holds it's own state,
|
||||
* so it's not necessary to update instruction pointer etc while it's working.
|
||||
* Assembled instructions are placed inside a dedicated vector, but generated
|
||||
* machine code is accessing
|
||||
* directly by the dedicated CodeIterator.
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @remarks This class isn't thread-safe.
|
||||
*/
|
||||
class StatefulAssembler {
|
||||
public:
|
||||
|
||||
/** Used only to indicate the need of the flush operation. */
|
||||
class SAFlush {
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a stateful assembler for the given assembler and assembler
|
||||
* context. Bear in mind that assembler and context are not copied in
|
||||
* any way and have to be valid as long as the stateful assembler in in
|
||||
* use. Parsing support can be enabled optionally using the third parameter.
|
||||
*
|
||||
* @param assembler The assembled that will be used to assemble the code.
|
||||
* @param context The assembler context.
|
||||
* @param enableParser Enables parsing support.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler(Assembler &assembler, AssemblerContext &context,
|
||||
bool enableParser = false) :
|
||||
_instructionBuilder(IB(FCML_TEXT("")), false),
|
||||
_assembler(assembler),
|
||||
_context(context),
|
||||
_codeLength(0) {
|
||||
// Create parser if needed.
|
||||
_parser = enableParser ? new Parser(assembler.getDialect()) : NULL;
|
||||
}
|
||||
|
||||
/** Destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~StatefulAssembler() {
|
||||
if (_parser) {
|
||||
delete _parser;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds instruction builder to the stateful assembler. Such a instruction
|
||||
* builder will be used then to assemble an instruction it represents.
|
||||
* Before any operation is performed, pending instruction is flushed if
|
||||
* there is any available.
|
||||
*
|
||||
* @param ib The instruction builder to be flushed.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw AssemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const IB &ib) {
|
||||
return add(ib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds instruction builder to the stateful assembler. Such a instruction
|
||||
* builder will be used then to assemble an instruction it represents.
|
||||
* Before any operation is performed, pending instruction is flushed if
|
||||
* there is any available.
|
||||
*
|
||||
* @param ib The instruction builder to be flushed.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw AssemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& add(const IB &ib) {
|
||||
flush();
|
||||
_instructionBuilder.setNotNull(true);
|
||||
_instructionBuilder.setValue(ib);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instruction builder for the given mnemonic.
|
||||
*
|
||||
* @param mnemonic The instruction mnemonic.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw AssemblingFailedException, ParsingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const fcml_cstring &mnemonic) {
|
||||
return inst(mnemonic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instruction builder for the given mnemonic.
|
||||
*
|
||||
* @param mnemonic The instruction mnemonic.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw AssemblingFailedException, ParsingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& inst(const fcml_cstring &mnemonic) {
|
||||
flush();
|
||||
if (_parser) {
|
||||
// Parse instruction and then pass it to the assembler.
|
||||
_parserContext.setIp(_context.getEntryPoint().getIP());
|
||||
ParserConfig &config = _parserContext.getConfig();
|
||||
config.setThrowExceptionOnError(true);
|
||||
_parser->parse(_parserContext, mnemonic, _parserResult);
|
||||
*this << _parserResult.getInstruction();
|
||||
} else {
|
||||
// Parser is not available, so treat this string as a full
|
||||
// instruction which have to be parsed.
|
||||
_instructionBuilder.setNotNull(true);
|
||||
_instructionBuilder.setValue(IB(mnemonic));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new register operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param reg The register.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const Register ®) {
|
||||
return op(Operand(reg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new immediate operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param imm The immediate value.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const Integer &imm) {
|
||||
return op(Operand(imm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new address operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param address The address.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const Address &address) {
|
||||
return op(Operand(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new far pointer operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param pointer The far pointer.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const FarPointer &pointer) {
|
||||
return op(Operand(pointer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an operand to the instruction builder associated with the buffer.
|
||||
*
|
||||
* @param operand The operand to be added.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const Operand &operand) {
|
||||
return op(operand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an operand to the instruction builder associated with the buffer.
|
||||
*
|
||||
* @param operand The operand to be added..
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& op(const Operand &operand) {
|
||||
if (!_instructionBuilder.isNotNull()) {
|
||||
throw IllegalStateException(
|
||||
FCML_TEXT("No instruction builder available."));
|
||||
}
|
||||
IB &ib = _instructionBuilder.getValue();
|
||||
ib.op(operand);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new register operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param reg The register.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& op(const Register ®) {
|
||||
return op(Operand(reg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new immediate operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param imm The immediate value.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& op(const Integer &imm) {
|
||||
return op(Operand(imm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new address operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param address The address.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& op(const Address &address) {
|
||||
return op(Operand(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new far pointer operand to the instruction builder associated
|
||||
* with the buffer.
|
||||
*
|
||||
* @param pointer The far pointer.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw IllegalStateException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& op(const FarPointer &pointer) {
|
||||
return op(Operand(pointer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes the instruction builder.
|
||||
* @param indic Flush indicator.
|
||||
* @return The stateful assembler itself.
|
||||
* @throw AssemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const SAFlush &indic) {
|
||||
flush();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles an instruction in the given instruction builder.
|
||||
*
|
||||
* @param instruction Instruction to be assembled.
|
||||
* @return Stateful assembler.
|
||||
* @throw AssemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const Instruction &instruction) {
|
||||
return inst(instruction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a prefix to the instruction being built.
|
||||
* @param prefix The prefix to be added.
|
||||
* @return The instruction builder with the new prefix set for it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const InstructionPrefix &prefix) {
|
||||
return set(prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an instruction level hint to the instruction being built.
|
||||
* @param hint The hint to be added.
|
||||
* @return The instruction builder with the new hint added to it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const InstructionHint &hint) {
|
||||
return set(hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an operand level hint to the instruction being built.
|
||||
* @param hint The hint to be added.
|
||||
* @return The instruction builder with the new hint added to it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& operator <<(const OperandHint &hint) {
|
||||
return set(hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a prefix to the instruction being built.
|
||||
* @param prefix The prefix to be added.
|
||||
* @return The instruction builder with the new prefix set for it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& set(const InstructionPrefix &prefix) {
|
||||
if (!_instructionBuilder.isNotNull()) {
|
||||
throw IllegalStateException(
|
||||
FCML_TEXT("No instruction builder available."));
|
||||
}
|
||||
_instructionBuilder.getValue() << prefix;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an instruction level hint to the instruction being built.
|
||||
* @param hint The hint to be added.
|
||||
* @return The instruction builder with the new hint added to it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& set(const InstructionHint &hint) {
|
||||
if (!_instructionBuilder.isNotNull()) {
|
||||
throw IllegalStateException(
|
||||
FCML_TEXT("No instruction builder available."));
|
||||
}
|
||||
_instructionBuilder.getValue() << hint;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an operand level hint to the instruction being built.
|
||||
* @param hint The hint to be added.
|
||||
* @return The instruction builder with the new hint added to it.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& set(const OperandHint &hint) {
|
||||
if (!_instructionBuilder.isNotNull()) {
|
||||
throw IllegalStateException(
|
||||
FCML_TEXT("No instruction builder available."));
|
||||
}
|
||||
_instructionBuilder.getValue() << hint;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles an instruction in the given instruction builder.
|
||||
*
|
||||
* @param instruction Instruction to be assembled.
|
||||
* @return Stateful assembler.
|
||||
* @throw AssemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulAssembler& inst(const Instruction &instruction) {
|
||||
|
||||
// Flush pending instruction if there is any.
|
||||
flush();
|
||||
|
||||
// Just in case.
|
||||
AssemblerConf &config = _context.getConfig();
|
||||
config.setIncrementIp(true);
|
||||
config.setThrowExceptionOnError(true);
|
||||
|
||||
// Assembler the instruction.
|
||||
_assembler.assemble(_context, instruction, _result);
|
||||
|
||||
// Store the chosen assembled instruction for future use.
|
||||
const AssembledInstruction *assembledInstruction =
|
||||
_result.getChosenInstruction();
|
||||
if (assembledInstruction) {
|
||||
_assembledInstructions.push_back(*assembledInstruction);
|
||||
_codeLength += assembledInstruction->getCodeLength();
|
||||
} else {
|
||||
throw AssemblingFailedException(
|
||||
FCML_TEXT("Chosen instruction hasn't been set. It seems "
|
||||
"that the instruction chooser isn't working "
|
||||
"correctly."));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets iterator which allows to iterate through the whole machine
|
||||
* code byte by byte.
|
||||
*
|
||||
* @return Iterator instance.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
CodeIterator getCodeIterator() {
|
||||
flush();
|
||||
return CodeIterator(_assembledInstructions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all chosen assembled instructions.
|
||||
*
|
||||
* @return All assembled instructions available in the buffer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
std::vector<AssembledInstruction>& getAssembledInstructions() {
|
||||
flush();
|
||||
return _assembledInstructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the code length of all assembled instructions available.
|
||||
*
|
||||
* @return The code length.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_usize getCodeLength() {
|
||||
flush();
|
||||
return _codeLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assembles all pending instructions.
|
||||
* @since 1.1.0
|
||||
* @throw AssemblingFailedException
|
||||
*/
|
||||
void flush() {
|
||||
if (_instructionBuilder.isNotNull()) {
|
||||
// Build an instruction using the instruction builder.
|
||||
Instruction instruction = _instructionBuilder.getValue().build();
|
||||
// And clean the builder, is everything succeed.
|
||||
_instructionBuilder.setNotNull(false);
|
||||
// Assemble the instruction.
|
||||
*this << instruction;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates flush indicated for "shift" operators.
|
||||
* @return Flush indicator.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
static SAFlush FLUSH() {
|
||||
return SAFlush();
|
||||
}
|
||||
|
||||
/** Gets configuration used by parser if parsing is supported.
|
||||
* @return Parser configuration.
|
||||
*/
|
||||
const ParserConfig& getParserConfig() const {
|
||||
return _parserContext.getConfig();
|
||||
}
|
||||
|
||||
/** Gets configuration used by parser if parsing is supported.
|
||||
* @return Parser configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
ParserConfig& getParserConfig() {
|
||||
return _parserContext.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets symbol table used together with the parser.
|
||||
* @return The symbol table used by the parser.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const SymbolTable* getSymbolTable() const {
|
||||
return _parserContext.getSymbolTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets symbol table used together with the parser.
|
||||
* @return The symbol table used by the parser.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
SymbolTable* getSymbolTable() {
|
||||
return _parserContext.getSymbolTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new symbol table for the parser.
|
||||
* @param symbolTable The new symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setSymbolTable(SymbolTable *symbolTable) {
|
||||
_parserContext.setSymbolTable(symbolTable);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** An instruction parser. */
|
||||
Parser *_parser;
|
||||
/** Parser result used when parsing is supported. */
|
||||
ParserResult _parserResult;
|
||||
/** Parser context. */
|
||||
ParserContext _parserContext;
|
||||
/** A disassembled result used by the assembler when needed. */
|
||||
AssemblerResult _result;
|
||||
/** Currently used instruction builder. */
|
||||
Nullable<IB> _instructionBuilder;
|
||||
/* Assembler used to assemble code. */
|
||||
Assembler &_assembler;
|
||||
/** Assembler context. */
|
||||
AssemblerContext &_context;
|
||||
// Assembled instructions.
|
||||
std::vector<AssembledInstruction> _assembledInstructions;
|
||||
/** Length of the code assembled so far. */
|
||||
fcml_usize _codeLength;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_STATEFUL_ASSEMBLER_HPP_ */
|
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_stateful_disassembler.hpp
|
||||
* Stateful FCML disassembler implementation.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_STATEFUL_DISASSEMBLER_HPP_
|
||||
#define FCML_STATEFUL_DISASSEMBLER_HPP_
|
||||
|
||||
#include "fcml_disassembler.hpp"
|
||||
#include "fcml_renderer.hpp"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/** Stateful disassembler can be used when you have to disassemble a larger
|
||||
* piece of code one instruction by one.
|
||||
* It also supports rendering directly using internally managed renderer.
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @remarks This class isn't thread-safe.
|
||||
*/
|
||||
class StatefulDisassembler {
|
||||
public:
|
||||
|
||||
/** Creates a stateful disassembler for given FCML disassembler and context.
|
||||
* Rendering support can be enabled optionally.
|
||||
* @param disassembler The classic FCML disassembler used to
|
||||
* disassemble instructions.
|
||||
* @param context The disassembler context.
|
||||
* @param enableRendering Enables instruction rendering, which is
|
||||
* disabled by default.
|
||||
*/
|
||||
StatefulDisassembler(Disassembler &disassembler,
|
||||
DisassemblerContext &context, bool enableRendering = false) :
|
||||
_disassembler(disassembler),
|
||||
_disassemblerContext(context) {
|
||||
_renderer = enableRendering ?
|
||||
new Renderer(disassembler.getDialect()) : NULL;
|
||||
// End of line characters to be used when instructions are
|
||||
// rendered directly to the output stream.
|
||||
#if defined(_WIN32)
|
||||
_endOfLine = FCML_TEXT( "\r\n" );
|
||||
#else
|
||||
_endOfLine = FCML_TEXT("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
virtual ~StatefulDisassembler() {
|
||||
if (_renderer) {
|
||||
delete _renderer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disassembles the next instruction pointed by the disassembler state.
|
||||
* @param[out] instruction The destination instruction model.
|
||||
* @return A reference to the stateful disassembler.
|
||||
* @throws DisassemblingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulDisassembler& operator >>(Instruction &instruction) {
|
||||
|
||||
// IP has to be incremented automatically, instruction by instruction.
|
||||
DisassemblerConf &config = _disassemblerContext.getDisassemblerConf();
|
||||
config.setIncrementIp(true);
|
||||
config.setThrowExceptionOnError(true);
|
||||
|
||||
// We don't care about error handling here, because it's disassembler
|
||||
// who is responsible for correctly handling it.
|
||||
_disassembler.disassemble(_disassemblerContext, _disassemblerResult);
|
||||
|
||||
instruction = _disassemblerResult.getInstruction();
|
||||
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Disassembles the next instruction from the buffer and renders it.
|
||||
* @param[out] instruction Destination string for the instruction.
|
||||
* @return A reference to the stateful disassembler.
|
||||
* @throws DisassemblingFailedException,
|
||||
* IllegalStateException,
|
||||
* RenderingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulDisassembler& operator >>(fcml_cstring &instruction) {
|
||||
|
||||
if (!_renderer) {
|
||||
throw IllegalStateException(FCML_TEXT("Rendering is disabled."));
|
||||
}
|
||||
|
||||
// IP has to be incremented automatically, instruction by instruction.
|
||||
DisassemblerConf &config = _disassemblerContext.getDisassemblerConf();
|
||||
config.setIncrementIp(true);
|
||||
config.setThrowExceptionOnError(true);
|
||||
|
||||
_disassembler.disassemble(_disassemblerContext, _disassemblerResult);
|
||||
|
||||
_rendererConfig.setThrowExceptionOnError(true);
|
||||
_renderer->render(_rendererConfig, _disassemblerResult, instruction);
|
||||
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Disassembles the next instruction from the buffer and renders it
|
||||
* directly into the output stream.
|
||||
* @param[out] ostream The output stream.
|
||||
* @return A reference to the stateful disassembler.
|
||||
* @throws DisassemblingFailedException,
|
||||
* IllegalStateException,
|
||||
* RenderingFailedException
|
||||
* @since 1.1.0
|
||||
*/
|
||||
StatefulDisassembler& operator >>(fcml_costream &ostream) {
|
||||
|
||||
fcml_cstring instruction;
|
||||
|
||||
// Render the next instruction into a string.
|
||||
*this >> instruction;
|
||||
|
||||
// Appends the instruction into an output stream.
|
||||
ostream << instruction << _endOfLine;
|
||||
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets renderer configuration used by the instruction buffer.
|
||||
* @return The renderer configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
RenderConfig& getRendererConfig() {
|
||||
return _rendererConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets renderer configuration used by the internally managed
|
||||
* instruction renderer.
|
||||
* @return The renderer configuration.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const RenderConfig& getRendererConfig() const {
|
||||
return _rendererConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets end of line characters sequence used by the renderer.
|
||||
*
|
||||
* @return End of line characters sequence used by the renderer.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const fcml_cstring& getEndOfLine() const {
|
||||
return _endOfLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets dedicated end of line characters.
|
||||
*
|
||||
* @param endOfLine A sequence of characters used as line ending.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setEndOfLine(const fcml_cstring &endOfLine) {
|
||||
_endOfLine = endOfLine;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** End of line character sequence. */
|
||||
fcml_cstring _endOfLine;
|
||||
/** Disassembler result used when disassembling instructions. */
|
||||
DisassemblerResult _disassemblerResult;
|
||||
/** The disassembler used to disassemble the code. */
|
||||
Disassembler &_disassembler;
|
||||
/** Disassembler context pointing to the machine code. */
|
||||
DisassemblerContext &_disassemblerContext;
|
||||
/** Renderer configuration used when instructions have to be rendered. */
|
||||
RenderConfig _rendererConfig;
|
||||
/** Optional renderer used only when instructions are rendered. */
|
||||
Renderer *_renderer;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* FCML_STATEFUL_DISASSEMBLER_HPP_ */
|
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_symbols.h
|
||||
* API for symbols handling. Currently used only by parsers.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_SYMBOLS_H_
|
||||
#define FCML_SYMBOLS_H_
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
#include "fcml_common.h"
|
||||
#include "fcml_errors.h"
|
||||
|
||||
/** Type for symbol tables. */
|
||||
typedef fcml_ptr fcml_st_symbol_table;
|
||||
|
||||
/*********************************
|
||||
* Symbols.
|
||||
*********************************/
|
||||
|
||||
/** Represents one named symbol with associated value. */
|
||||
typedef struct fcml_st_symbol {
|
||||
/* The symbol name. */
|
||||
fcml_string symbol;
|
||||
/* The symbol value. */
|
||||
fcml_int64_t value;
|
||||
} fcml_st_symbol;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Allocates new symbol on FCML library heap.
|
||||
* This function should be always used when symbols
|
||||
* are added using fcml_fn_symbol_add() function.
|
||||
* @return Allocated symbol or NULL if allocation failed.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_symbol* LIB_CALL fcml_fn_symbol_alloc(
|
||||
const fcml_string symbol, fcml_int64_t value);
|
||||
|
||||
/**
|
||||
* Frees symbol allocated by FCML library.
|
||||
* @param symbol The symbol to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_symbol_free(fcml_st_symbol *symbol);
|
||||
|
||||
/**
|
||||
* Allocates new symbol table.
|
||||
* @return The allocated symbol table or NULL if something failed.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_symbol_table LIB_CALL fcml_fn_symbol_table_alloc();
|
||||
|
||||
/**
|
||||
* Adds new symbol to the symbol table.
|
||||
* This function is more secure than fcml_fn_symbol_add() because it
|
||||
* always allocates new symbol instance internally, so you do not have
|
||||
* to pay attention not to pass the symbol allocated on the different heap
|
||||
* to the symbol table. After the symbol has been properly added you can
|
||||
* safely free the name because this function duplicates the name
|
||||
* to the symbol needs. Of course the symbol as well as the duplicated name
|
||||
* are freed by fcml_fn_symbol_table_free() function. You can also
|
||||
* free it on your own if the symbol is not managed by symbol table
|
||||
* using fcml_fn_symbol_free() function.
|
||||
* @param symbol_table The symbol table.
|
||||
* @param symbol The symbol name.
|
||||
* @param value The symbol value.
|
||||
* @see fcml_fn_symbol_table_free
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_symbol_add_raw(
|
||||
fcml_st_symbol_table symbol_table, const fcml_string symbol,
|
||||
fcml_int64_t value);
|
||||
|
||||
/**
|
||||
* Adds existing symbol to the symbol table.
|
||||
* Remember that only symbols allocated on FCML heap should be
|
||||
* added there. Of course in some cases heaps are shared so
|
||||
* it will works without any problems but even if they are you
|
||||
* <b>should</b> use fcml_fn_symbol_table_alloc() function to allocate
|
||||
* every symbol.
|
||||
*
|
||||
* @param symbol_table The symbol table where new symbol should be placed.
|
||||
* @param symbol The symbol to be added.
|
||||
* @return Error code or FCML_CEH_GEC_NO_ERROR.
|
||||
*/
|
||||
LIB_EXPORT fcml_ceh_error LIB_CALL fcml_fn_symbol_add(
|
||||
fcml_st_symbol_table symbol_table, const fcml_st_symbol *symbol);
|
||||
|
||||
/**
|
||||
* Removes the symbol from the symbol table.
|
||||
* The removed symbol is automatically freed.
|
||||
* @param symbol_table The symbol table.
|
||||
* @param symbol The name of the symbol to remove.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_symbol_remove(
|
||||
fcml_st_symbol_table symbol_table, const fcml_string symbol);
|
||||
|
||||
/**
|
||||
* Gets the symbol with the given name from the symbol table.
|
||||
* @param symbol_table The symbol table.
|
||||
* @param symbol The name of the symbol to get from the table.
|
||||
* @return The pointer to the symbol or NULL if there is no such symbol
|
||||
* in the symbol table.
|
||||
*/
|
||||
LIB_EXPORT fcml_st_symbol* LIB_CALL fcml_fn_symbol_get(
|
||||
fcml_st_symbol_table symbol_table, const fcml_string symbol);
|
||||
|
||||
/**
|
||||
* Removes all symbols from the symbol table.
|
||||
* Removes and frees all symbols from the given symbol table
|
||||
* but does not free the symbol table itself.
|
||||
* @param symbol_table The symbol table to be cleared.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_symbol_remove_all(
|
||||
fcml_st_symbol_table symbol_table);
|
||||
|
||||
/**
|
||||
* Frees a symbol table.
|
||||
* Frees all symbols as well as the symbol table itself.
|
||||
* @param symbol_table A symbol table to be freed.
|
||||
*/
|
||||
LIB_EXPORT void LIB_CALL fcml_fn_symbol_table_free(
|
||||
fcml_st_symbol_table symbol_table);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FCML_SYMBOLS_H_ */
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2019 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_symbols.hpp
|
||||
* C++ API for symbols handling. Currently used only by parsers.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_SYMBOLS_HPP_
|
||||
#define FCML_SYMBOLS_HPP_
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "fcml_common.hpp"
|
||||
#include "fcml_symbols.h"
|
||||
|
||||
namespace fcml {
|
||||
|
||||
/**
|
||||
* Represents one named symbol with associated value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class Symbol {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an empty symbol.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Symbol() :
|
||||
_value(0) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a symbol instance for the given name and value.
|
||||
*
|
||||
* @param name The symbol name.
|
||||
* @param value The symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Symbol(const fcml_cstring &name, fcml_int64_t value) :
|
||||
_name(name), _value(value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
operator fcml_uint64_t() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
operator fcml_int64_t() const {
|
||||
return static_cast<fcml_int64_t>(_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets true if symbol is empty.
|
||||
*
|
||||
* @return True if symbol is empty.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool isEmpty() const {
|
||||
return _name.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol name.
|
||||
*
|
||||
* @return The symbol name.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
const fcml_cstring& getName() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol value.
|
||||
*
|
||||
* @return The symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_uint64_t getValue() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new symbol name.
|
||||
*
|
||||
* @param name The symbol name.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setName(const fcml_cstring &name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new symbol value.
|
||||
*
|
||||
* @param value The symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void setValue(fcml_uint64_t value) {
|
||||
_value = value;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Symbol name.
|
||||
fcml_cstring _name;
|
||||
// Symbol value.
|
||||
fcml_uint64_t _value;
|
||||
|
||||
};
|
||||
|
||||
/* Due to the performance purposes and the way symbol table is managed
|
||||
* internally, it has to be wrapped directly without doing any conversions
|
||||
* when needed.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class SymbolTable: public NonCopyable {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates an empty symbol table.
|
||||
* @throw InitException The symbol table can't be allocated.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
SymbolTable() :
|
||||
_symbolTable(NULL) {
|
||||
_symbolTable = ::fcml_fn_symbol_table_alloc();
|
||||
if (!_symbolTable) {
|
||||
throw InitException(
|
||||
FCML_TEXT(
|
||||
"Symbol table can not be initialized correctly."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
virtual ~SymbolTable() {
|
||||
if (_symbolTable) {
|
||||
::fcml_fn_symbol_table_free(_symbolTable);
|
||||
_symbolTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class SymbolTableAware;
|
||||
|
||||
/**
|
||||
* Gets native FCML symbol table.
|
||||
* @return The native symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_st_symbol_table& getSymbolTable() {
|
||||
return _symbolTable;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Adds a new symbol to the table.
|
||||
*
|
||||
* @param symbolName The symbol name.
|
||||
* @param value The symbol value.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void add(const fcml_cstring &symbolName, fcml_int64_t value) {
|
||||
if (::fcml_fn_symbol_add_raw(_symbolTable, symbolName.c_str(), value)
|
||||
== FCML_CEH_GEC_OUT_OF_MEMORY) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes symbol from the table.
|
||||
*
|
||||
* @param symbolName The symbol name.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
void remove(const fcml_cstring &symbolName) {
|
||||
const fcml_string key = symbolName.c_str();
|
||||
::fcml_fn_symbol_remove(_symbolTable, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets true if there is a symbol for the given name in the table.
|
||||
*
|
||||
* @param symbolName The symbol name.
|
||||
* @return true If symbol of the name exists in the table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
bool contains(const fcml_cstring &symbolName) const {
|
||||
return ::fcml_fn_symbol_get(_symbolTable, symbolName.c_str()) != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the symbol of the given name. Checks Symbol.isEmpty method of the
|
||||
* returned symbol to check if there is such a symbol.
|
||||
*
|
||||
* @param symbolName The symbol name.
|
||||
* @return The found symbol.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
Symbol get(const fcml_cstring &symbolName) const {
|
||||
Symbol symbol;
|
||||
fcml_st_symbol *found_symbol = ::fcml_fn_symbol_get(_symbolTable,
|
||||
symbolName.c_str());
|
||||
if (found_symbol) {
|
||||
symbol.setName(found_symbol->symbol);
|
||||
symbol.setValue(found_symbol->value);
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
private:
|
||||
/** The native FCML symbol table. */
|
||||
fcml_st_symbol_table _symbolTable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive from this class if you really need access to the native symbol table.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
class SymbolTableAware {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Extracts the native symbol table for the given symbol table wrapper.
|
||||
* @param symbolTable The symbol table wrapper.
|
||||
* @since 1.1.0
|
||||
*/
|
||||
fcml_st_symbol_table& extractSymbolTable(SymbolTable &symbolTable) {
|
||||
return symbolTable.getSymbolTable();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* FCML_SYMBOLS_HPP_ */
|
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* FCML - Free Code Manipulation Library.
|
||||
* Copyright (C) 2010-2015 Slawomir Wojtasiak
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/** @file fcml_types.h
|
||||
* Types declarations.
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Slawomir Wojtasiak. All rights reserved.
|
||||
* This project is released under the GNU Lesser General Public License.
|
||||
*/
|
||||
|
||||
#ifndef FCML_TYPES_H_
|
||||
#define FCML_TYPES_H_
|
||||
|
||||
/* If config.h is available, we depend on it; otherwise we give
|
||||
* the responsibility to handle headers appropriately to the compiler runtime.
|
||||
**/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#ifdef HAVE_STDDEF_H
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#else
|
||||
#if defined(_MSC_VER) && defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#define FCML_MSCC
|
||||
/* Disable unit specific lexer features. */
|
||||
#define YY_NO_INPUT 1
|
||||
#define YY_NO_UNISTD_H 1
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "fcml_lib_export.h"
|
||||
|
||||
/** Used to code literal strings. It will be useful if FCML supports UNICODE in the future. */
|
||||
#define FCML_TEXT(x) x
|
||||
#define _FT(x) FCML_TEXT(x)
|
||||
|
||||
#ifdef FCML_MSCC
|
||||
|
||||
#define FCML_PRI_INT8_DEC "%d"
|
||||
#define FCML_PRI_INT16_DEC "%d"
|
||||
#define FCML_PRI_INT32_DEC "%d"
|
||||
#define FCML_PRI_INT64_DEC "%lld"
|
||||
|
||||
#define FCML_PRI_UINT8_DEC "%u"
|
||||
#define FCML_PRI_UINT16_DEC "%u"
|
||||
#define FCML_PRI_UINT32_DEC "%u"
|
||||
#define FCML_PRI_UINT64_DEC "%llu"
|
||||
|
||||
#define FCML_PRI_INT8_HEX "%02x"
|
||||
#define FCML_PRI_INT16_HEX "%04x"
|
||||
#define FCML_PRI_INT32_HEX "%08x"
|
||||
#define FCML_PRI_INT64_HEX "%016llx"
|
||||
|
||||
#define FCML_PRI_INT8_HEX_NO_ZEROS "%x"
|
||||
#define FCML_PRI_INT16_HEX_NO_ZEROS "%x"
|
||||
#define FCML_PRI_INT32_HEX_NO_ZEROS "%x"
|
||||
#define FCML_PRI_INT64_HEX_NO_ZEROS "%llx"
|
||||
|
||||
typedef int fcml_int;
|
||||
typedef int fcml_bool;
|
||||
typedef __int8 fcml_int8_t;
|
||||
typedef unsigned __int8 fcml_uint8_t;
|
||||
typedef __int16 fcml_int16_t;
|
||||
typedef unsigned __int16 fcml_uint16_t;
|
||||
typedef __int32 fcml_int32_t;
|
||||
typedef unsigned __int32 fcml_uint32_t;
|
||||
typedef __int64 fcml_int64_t;
|
||||
typedef unsigned __int64 fcml_uint64_t;
|
||||
|
||||
/* Signed integers. */
|
||||
#define FCML_INT64_MAX _I64_MAX
|
||||
#define FCML_INT64_MIN _I64_MIN
|
||||
#define FCML_INT32_MAX INT_MAX
|
||||
#define FCML_INT32_MIN INT_MIN
|
||||
#define FCML_INT16_MAX SHRT_MAX
|
||||
#define FCML_INT16_MIN SHRT_MIN
|
||||
#define FCML_INT8_MAX SCHAR_MAX
|
||||
#define FCML_INT8_MIN SCHAR_MIN
|
||||
|
||||
/* Unsigned integers. */
|
||||
#define FCML_UINT8_MAX UCHAR_MAX
|
||||
#define FCML_UINT16_MAX USHRT_MAX
|
||||
#define FCML_UINT32_MAX UINT_MAX
|
||||
#define FCML_UINT64_MAX _UI64_MAX
|
||||
|
||||
#else
|
||||
|
||||
#ifdef PRId8
|
||||
#define FCML_PRI_INT8_DEC "%" PRId8
|
||||
#endif
|
||||
#ifdef PRId16
|
||||
#define FCML_PRI_INT16_DEC "%" PRId16
|
||||
#endif
|
||||
#ifdef PRId32
|
||||
#define FCML_PRI_INT32_DEC "%" PRId32
|
||||
#endif
|
||||
#ifdef PRId64
|
||||
#define FCML_PRI_INT64_DEC "%" PRId64
|
||||
#endif
|
||||
|
||||
#ifdef PRIu8
|
||||
#define FCML_PRI_UINT8_DEC "%" PRIu8
|
||||
#endif
|
||||
#ifdef PRIu16
|
||||
#define FCML_PRI_UINT16_DEC "%" PRIu16
|
||||
#endif
|
||||
#ifdef PRIu32
|
||||
#define FCML_PRI_UINT32_DEC "%" PRIu32
|
||||
#endif
|
||||
#ifdef PRIu64
|
||||
#define FCML_PRI_UINT64_DEC "%" PRIu64
|
||||
#endif
|
||||
|
||||
#ifdef PRIx8
|
||||
#define FCML_PRI_INT8_HEX "%02" PRIx8
|
||||
#endif
|
||||
#ifdef PRIx16
|
||||
#define FCML_PRI_INT16_HEX "%04" PRIx16
|
||||
#endif
|
||||
#ifdef PRIx32
|
||||
#define FCML_PRI_INT32_HEX "%08" PRIx32
|
||||
#endif
|
||||
#ifdef PRIx64
|
||||
#define FCML_PRI_INT64_HEX "%016" PRIx64
|
||||
#endif
|
||||
|
||||
#ifdef PRIx8
|
||||
#define FCML_PRI_INT8_HEX_NO_ZEROS "%" PRIx8
|
||||
#endif
|
||||
#ifdef PRIx16
|
||||
#define FCML_PRI_INT16_HEX_NO_ZEROS "%" PRIx16
|
||||
#endif
|
||||
#ifdef PRIx32
|
||||
#define FCML_PRI_INT32_HEX_NO_ZEROS "%" PRIx32
|
||||
#endif
|
||||
#ifdef PRIx64
|
||||
#define FCML_PRI_INT64_HEX_NO_ZEROS "%" PRIx64
|
||||
#endif
|
||||
|
||||
typedef int fcml_int;
|
||||
typedef unsigned int fcml_uint;
|
||||
typedef int fcml_bool;
|
||||
typedef int8_t fcml_int8_t;
|
||||
typedef uint8_t fcml_uint8_t;
|
||||
typedef int16_t fcml_int16_t;
|
||||
typedef uint16_t fcml_uint16_t;
|
||||
typedef int32_t fcml_int32_t;
|
||||
typedef uint32_t fcml_uint32_t;
|
||||
typedef int64_t fcml_int64_t;
|
||||
typedef uint64_t fcml_uint64_t;
|
||||
|
||||
/* Signed integers. */
|
||||
#define FCML_INT64_MAX INT64_MAX
|
||||
#define FCML_INT64_MIN INT64_MIN
|
||||
#define FCML_INT32_MAX INT32_MAX
|
||||
#define FCML_INT32_MIN INT32_MIN
|
||||
#define FCML_INT16_MAX INT16_MAX
|
||||
#define FCML_INT16_MIN INT16_MIN
|
||||
#define FCML_INT8_MAX INT8_MAX
|
||||
#define FCML_INT8_MIN INT8_MIN
|
||||
|
||||
/* Unsigned integers. */
|
||||
#define FCML_UINT8_MAX UINT8_MAX
|
||||
#define FCML_UINT16_MAX UINT16_MAX
|
||||
#define FCML_UINT32_MAX UINT32_MAX
|
||||
#define FCML_UINT64_MAX UINT64_MAX
|
||||
|
||||
#endif
|
||||
|
||||
typedef char fcml_char;
|
||||
#define fcml_string char*
|
||||
typedef float fcml_float;
|
||||
typedef void* fcml_ptr;
|
||||
typedef fcml_uint32_t fcml_flags;
|
||||
|
||||
typedef fcml_uint32_t fcml_usize;
|
||||
typedef fcml_int32_t fcml_size;
|
||||
|
||||
#define FCML_TRUE 1
|
||||
#define FCML_FALSE 0
|
||||
|
||||
/* Macro for bit manipulations. */
|
||||
|
||||
#define FCML_TP_SET_BIT(x,y) ( ( x ) | ( 0x01 << ( y ) ) )
|
||||
#define FCML_TP_GET_BIT(x,y) ( ( x >> y ) & 0x01 )
|
||||
#define FCML_TP_CLEAR_BIT(x,y) ( ( x ) &= ~( 1 << ( y ) ) )
|
||||
|
||||
/* Nulleable types. */
|
||||
|
||||
typedef struct fcml_nuint8_t {
|
||||
fcml_uint8_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nuint8_t;
|
||||
|
||||
typedef struct fcml_nuint16_t {
|
||||
fcml_uint16_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nuint16_t;
|
||||
|
||||
typedef struct fcml_nuint32_t {
|
||||
fcml_uint32_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nuint32_t;
|
||||
|
||||
typedef struct fcml_nuint64_t {
|
||||
fcml_uint64_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nuint64_t;
|
||||
|
||||
typedef struct fcml_nint8_t {
|
||||
fcml_int8_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nint8_t;
|
||||
|
||||
typedef struct fcml_nint16_t {
|
||||
fcml_int16_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nint16_t;
|
||||
|
||||
typedef struct fcml_nint32_t {
|
||||
fcml_int32_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nint32_t;
|
||||
|
||||
typedef struct fcml_nint64_t {
|
||||
fcml_int64_t value;
|
||||
fcml_bool is_not_null;
|
||||
} fcml_nint64_t;
|
||||
|
||||
typedef struct fcml_st_integer {
|
||||
fcml_usize size;
|
||||
fcml_bool is_signed;
|
||||
// Data fields.
|
||||
fcml_int8_t int8;
|
||||
fcml_int16_t int16;
|
||||
fcml_int32_t int32;
|
||||
fcml_int64_t int64;
|
||||
} fcml_st_integer;
|
||||
|
||||
#define FCML_SET_VALUE(x, y) x.value = y; x.is_not_null = FCML_TRUE;
|
||||
#define FCML_SET_NULL(x) x.value = 0; x.is_not_null = FCML_FALSE;
|
||||
#define FCML_IS_NULL(x) ((x).is_not_null == FCML_FALSE)
|
||||
|
||||
#endif /* FCML_TYPES_H_ */
|
Loading…
Reference in new issue