You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
227 lines
6.3 KiB
227 lines
6.3 KiB
/*
|
|
* 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_ */
|