Repository URL to install this package:
|
Version:
9.0~240925-3.fc42 ▾
|
/*
Interactive disassembler (IDA).
Copyright (c) 2005-2024 Hex-Rays SA <support@hex-rays.com>
ALL RIGHTS RESERVED.
Merge functionality.
Various helper definitions for processor modules.
*/
#include <mergemod.hpp>
// PROCMOD_NAME is the name of the processor module name (e.g. "arm").
// PROCMODE_T is the name of the module specific data structure.
// usually PROCMODE_NAME is defined and we derive PROCMODE_T from it, but it
//
// PROCMOD_NAME is used as a prefix for the 'idpoptions' names.
// example: arm.analysis.simplify_instructions
// where arm is PROCMOD_NAME, and in the idbattr_info_t array there is "analysis.simplify_instructions"
//
#ifndef PROCMOD_T
#define APPEND_SUFF(name, suff) name ## suff
#define TAPPEND_SUFF(name, suff) APPEND_SUFF(name, suff)
#define PROCMOD_T TAPPEND_SUFF(PROCMOD_NAME, _t)
#define PROCMOD_HELPER_T TAPPEND_SUFF(PROCMOD_NAME, _moddiff_helper_t)
#endif
// Also, PROCMOD_NODE_NAME should be defined: it is the name of the module netnode
// The standard module parameters for merging.
// The 'insert_after' argument is alwats MERGE_KIND_INF for processor modules
// because in this case the kernel puts the merge handler for idpoptions
// immediately after
// Global settings/Processor specific/
// For example:
// Global settings/Processor specific/pc.state.gnulnx_til_loaded: true
// The address-dependent merge handlers are put at the end of the
// list inside the "Processor specific/" folder. Example:
// Processor specific/Pushinfo/08048492
// Processor specific/Pushinfo/080484D0
//
#define DEFINE_MERGE_HANDLER_PARAMS(insert_after) \
merge_handler_params_t mhp( \
md, \
"Processor specific", \
MERGE_KIND_NONE, /* allocate a merge kind */ \
insert_after, /* insert after what? */ \
MH_TERSE /* terse debug output; */ \
|MH_LISTEN) /* listen to merge events */
//--------------------------------------------------------------------------
// A helper definition for the 'device' attribute. Most module need only
// this definition, and nothing else:
static const idbattr_info_t idbattr_device_name[] =
{
IDI_DEVICE_ENTRY,
};
//--------------------------------------------------------------------------
// A local convenience macro for the definitions below
#define _PROCMOD_DIFF_HELPER(class_name, name, idbattrs) \
MODDATA_DIFF_HELPER(class_name, name, \
QSTRINGIZE(PROCMOD_NAME), PROCMOD_NODE_NAME, idbattrs)
//--------------------------------------------------------------------------
// A macro for std_moddata_diff_helper_t, see mergemod.hpp
// std_moddata_diff_helper_t requires the processor module to have the
// load_from_idb() method, which will be called at the end of merging.
// This macro is useful for merging the data stored in netnodes (not the fields
// of the processor specific data structure).
#define STD_PROCMOD_DIFF_HELPER(name, idbattrs) \
using PROCMOD_HELPER_T = std_moddata_diff_helper_t<PROCMOD_T>; \
_PROCMOD_DIFF_HELPER(PROCMOD_HELPER_T, name, idbattrs)
//--------------------------------------------------------------------------
// This macro uses moddata_diff_helper_t, does not require any method definitions.
// It is more simpler that the previous macro and should be used when the module
// does not have `idpoptions` except DEVICE, but has some ea-specific data.
// An example of such module: tms320c6.
#define SIMPLE_PROCMOD_DIFF_HELPER(name, idbattrs) \
_PROCMOD_DIFF_HELPER(moddata_diff_helper_t, name, idbattrs)
//--------------------------------------------------------------------------
/// Create and register a merge handler for internal processor module fields
/// param idbattrs descriptions of the fields
///
/// This macro should be used when the module has only idpoptions and no
/// address-dependent data.
#define DEFINE_SIMPLE_PROCMOD_HANDLER(idbattrs) \
void create_std_procmod_handlers(merge_data_t &md) \
{ \
DEFINE_MERGE_HANDLER_PARAMS(MERGE_KIND_INF); \
STD_PROCMOD_DIFF_HELPER(helper, idbattrs); \
return create_std_modmerge_handlers(mhp, data_id, helper); \
}
//--------------------------------------------------------------------------
/// Create and register a merge handler for internal processor module fields
/// and node values
/// param idbattrs descriptions of the module fields
/// param merge_node_info descriptions of node values
///
/// The most commonly used macro, when both idpoptions and address-dependent
/// data are present.
#define DEFINE_STD_PROCMOD_HANDLER(idbattrs, merge_node_info) \
void create_std_procmod_handlers(merge_data_t &md) \
{ \
DEFINE_MERGE_HANDLER_PARAMS(MERGE_KIND_INF); \
STD_PROCMOD_DIFF_HELPER(helper, idbattrs); \
return create_std_modmerge_handlers(mhp, data_id, helper, \
merge_node_info, qnumber(merge_node_info)); \
}
//--------------------------------------------------------------------------
/// The following functions can be useful in the helper class methods.
/// See examples in the SDK.
//--------------------------------------------------------------------------
inline void get_merging_func_name(qstring *out, ea_t func_ea, bool with_addr=false)
{
if ( get_name(out, func_ea) <= 0 )
out->sprnt("func<%a>", func_ea);
else if ( with_addr )
out->cat_sprnt(" at %a", func_ea);
}
//--------------------------------------------------------------------------
/// print string representation of flag values according to map bit=>name
inline qstring build_flags_info(uint64 flags, const idbattr_valmap_t *map, int n)
{
qstring str_flags;
for ( int i = 0; i < n; ++i )
if ( (flags & map[i].value) != 0 )
str_flags.cat_sprnt(" %s", map[i].valname);
return str_flags;
}