Files
sigmaker-ida/idasdk76/include/enum.hpp
2021-10-31 21:20:46 +02:00

372 lines
9.6 KiB
C++

/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2021 Hex-Rays
* ALL RIGHTS RESERVED.
*
* Enums and bitfields
* Bitfields will be abbreviated as "bf".
*
*/
#ifndef _ENUM_HPP
#define _ENUM_HPP
#include <nalt.hpp>
/*! \file enum.hpp
\brief Assembly level enum management
Enums and bitfields are represented as ::enum_t.
*/
typedef tid_t enum_t; ///< Enums and bitfields
typedef uval_t bmask_t; ///< unsigned value that describes a bitmask
///< a bit mask is 32/64 bits.
#define DEFMASK (bmask_t(-1)) ///< default bitmask
typedef uval_t const_t; ///< members of enums
/// Max number of identical constants allowed for one enum type
const uchar MAX_ENUM_SERIAL = 255;
/// Get number of declared ::enum_t types
idaman size_t ida_export get_enum_qty(void);
/// Get enum by its index in the list of enums (0..get_enum_qty()-1).
idaman enum_t ida_export getn_enum(size_t idx);
/// Get the index in the list of enums
idaman uval_t ida_export get_enum_idx(enum_t id);
/// Get enum by name
idaman enum_t ida_export get_enum(const char *name);
/// Is enum a bitfield?
/// (otherwise - plain enum, no bitmasks except for #DEFMASK are allowed)
idaman bool ida_export is_bf(enum_t id);
/// Is enum collapsed?
idaman bool ida_export is_enum_hidden(enum_t id);
/// Collapse enum
idaman bool ida_export set_enum_hidden(enum_t id, bool hidden);
/// Does enum come from type library?
idaman bool ida_export is_enum_fromtil(enum_t id);
/// Specify that enum comes from a type library
idaman bool ida_export set_enum_fromtil(enum_t id, bool fromtil);
/// Is a ghost copy of a local type?
idaman bool ida_export is_ghost_enum(enum_t id);
/// Specify that enum is a ghost copy of a local type
idaman bool ida_export set_enum_ghost(enum_t id, bool ghost);
/// Get name of enum
idaman ssize_t ida_export get_enum_name(qstring *out, enum_t id);
/// Get name of enum
/// \param[out] out buffer to hold the name
/// \param id enum id
/// \param flags \ref ENFL_
idaman ssize_t ida_export get_enum_name2(qstring *out, enum_t id, int flags=0);
/// \defgroup ENFL_ Enum name flags
/// Passed as 'flags' parameter to get_enum_name()
//@{
#define ENFL_REGEX 0x0001 ///< apply regular expressions to beautify the name
//@}
inline qstring get_enum_name(tid_t id, int flags=0)
{
qstring name;
get_enum_name2(&name, id, flags);
return name;
}
/// Get the width of a enum element
/// allowed values: 0 (unspecified),1,2,4,8,16,32,64
idaman size_t ida_export get_enum_width(enum_t id);
/// See comment for get_enum_width()
idaman bool ida_export set_enum_width(enum_t id, int width);
/// Get enum comment
idaman ssize_t ida_export get_enum_cmt(qstring *buf, enum_t id, bool repeatable);
/// Get the number of the members of the enum
idaman size_t ida_export get_enum_size(enum_t id);
/// Get flags determining the representation of the enum.
/// (currently they define the numeric base: octal, decimal, hex, bin) and signness.
idaman flags_t ida_export get_enum_flag(enum_t id);
/// Get a reference to an enum member by its name
idaman const_t ida_export get_enum_member_by_name(const char *name);
/// Get value of an enum member
idaman uval_t ida_export get_enum_member_value(const_t id);
/// Get the parent enum of an enum member
idaman enum_t ida_export get_enum_member_enum(const_t id);
/// Get bitmask of an enum member
idaman bmask_t ida_export get_enum_member_bmask(const_t id);
/// Find an enum member by enum, value and bitmask
/// \note if serial -1, return a member with any serial
idaman const_t ida_export get_enum_member(enum_t id, uval_t value, int serial, bmask_t mask);
/// \name Access to all used bitmasks in an enum
//@{
/// Get first bitmask in the enum (bitfield)
///
/// \param enum_id id of enum (bitfield)
/// \return the smallest bitmask for enum, or DEFMASK
///
idaman bmask_t ida_export get_first_bmask(enum_t id);
/// Get last bitmask in the enum (bitfield)
///
/// \param enum_id id of enum
/// \return the biggest bitmask for enum, or DEFMASK
idaman bmask_t ida_export get_last_bmask(enum_t id);
/// Get next bitmask in the enum (bitfield)
///
/// \param enum_id id of enum
/// \param value the current bitmask
/// \return value of a bitmask with value higher than the specified value, or DEFMASK
idaman bmask_t ida_export get_next_bmask(enum_t id, bmask_t bmask);
/// Get prev bitmask in the enum (bitfield)
///
/// \param enum_id id of enum
/// \param value the current bitmask
/// \return value of a bitmask with value lower than the specified value, or DEFMASK
idaman bmask_t ida_export get_prev_bmask(enum_t id, bmask_t bmask);
//@}
/// \name Access to all enum members with specified bitmask
/// \note these functions return values, not ::const_t!
//@{
idaman uval_t ida_export get_first_enum_member(enum_t id, bmask_t bmask=DEFMASK);
idaman uval_t ida_export get_last_enum_member(enum_t id, bmask_t bmask=DEFMASK);
idaman uval_t ida_export get_next_enum_member(enum_t id, uval_t value, bmask_t bmask=DEFMASK);
idaman uval_t ida_export get_prev_enum_member(enum_t id, uval_t value, bmask_t bmask=DEFMASK);
//@}
/// Get name of an enum member by const_t
idaman ssize_t ida_export get_enum_member_name(qstring *out, const_t id);
/// Get enum member's comment
idaman ssize_t ida_export get_enum_member_cmt(qstring *buf, const_t id, bool repeatable);
/// \name Access to all enum members with specified value and mask
/// A sample loop looks like this:
/// \code
/// const_t main_cid;
/// uchar serial;
/// for ( const_t cid=main_cid=get_first_serial_enum_member(&serial, id, v, mask);
/// cid != BADNODE;
/// cid = get_next_serial_enum_member(&serial, main_cid) )
/// {
/// ...
/// }
/// \endcode
/// The 'out_serial' argument of get_first_serial_enum_member/get_last_serial_enum_member can be NULL.
/// The 'in_out_serial' is required for the other functions.
//@{
idaman const_t ida_export get_first_serial_enum_member(uchar *out_serial, enum_t id, uval_t value, bmask_t bmask);
idaman const_t ida_export get_last_serial_enum_member(uchar *out_serial, enum_t id, uval_t value, bmask_t bmask);
idaman const_t ida_export get_next_serial_enum_member(uchar *in_out_serial, const_t first_cid);
idaman const_t ida_export get_prev_serial_enum_member(uchar *in_out_serial, const_t first_cid);
//@}
/// Enum member visitor - see for_all_enum_members().
/// Derive your visitor from this class.
struct enum_member_visitor_t
{
/// Implements action to take when enum member is visited.
/// \return nonzero to stop the iteration
virtual int idaapi visit_enum_member(const_t cid, uval_t value) = 0;
};
/// Visit all members of a given enum
idaman int ida_export for_all_enum_members(enum_t id, enum_member_visitor_t &cv);
/// Get serial number of an enum member
idaman uchar ida_export get_enum_member_serial(const_t cid);
/// Get corresponding type ordinal number
idaman int32 ida_export get_enum_type_ordinal(enum_t id);
/// Set corresponding type ordinal number
idaman void ida_export set_enum_type_ordinal(enum_t id, int32 ord);
//--------------------------------------------------------------------------
// MANIPULATION
/// Add new enum type.
/// - if idx==#BADADDR then add as the last idx
/// - if name==NULL then generate a unique name "enum_%d"
idaman enum_t ida_export add_enum(size_t idx, const char *name, flags_t flag);
/// Delete an enum type
idaman void ida_export del_enum(enum_t id);
/// Set serial number of enum.
/// Also see get_enum_idx().
idaman bool ida_export set_enum_idx(enum_t id, size_t idx);
/// Set 'bitfield' bit of enum (i.e. convert it to a bitfield)
idaman bool ida_export set_enum_bf(enum_t id, bool bf);
/// Set name of enum type
idaman bool ida_export set_enum_name(enum_t id,const char *name);
/// Set comment for enum type
idaman bool ida_export set_enum_cmt(enum_t id,const char *cmt,bool repeatable);
/// Set data representation flags
idaman bool ida_export set_enum_flag(enum_t id, flags_t flag);
/// Add member to enum type.
/// \return 0 if ok, otherwise one of \ref ENUM_MEMBER_
idaman int ida_export add_enum_member(
enum_t id,
const char *name,
uval_t value,
bmask_t bmask=DEFMASK);
/// \defgroup ENUM_MEMBER_ Add enum member result codes
/// Return values for add_enum_member()
//@{
#define ENUM_MEMBER_ERROR_NAME 1 ///< already have member with this name (bad name)
#define ENUM_MEMBER_ERROR_VALUE 2 ///< already have 256 members with this value
#define ENUM_MEMBER_ERROR_ENUM 3 ///< bad enum id
#define ENUM_MEMBER_ERROR_MASK 4 ///< bad bmask
#define ENUM_MEMBER_ERROR_ILLV 5 ///< bad bmask and value combination (~bmask & value != 0)
//@}
/// Delete member of enum type
idaman bool ida_export del_enum_member(enum_t id, uval_t value, uchar serial, bmask_t bmask);
/// Set name of enum member
idaman bool ida_export set_enum_member_name(const_t id, const char *name);
/// Set comment for enum member
inline bool set_enum_member_cmt(const_t id, const char *cmt, bool repeatable)
{
return set_enum_cmt(id, cmt, repeatable);
}
/// Is bitmask one bit?
inline THREAD_SAFE bool is_one_bit_mask(bmask_t mask)
{
return (mask & (mask-1)) == 0;
}
/// \name Work with the bitmask name & comment
//@{
idaman bool ida_export set_bmask_name(enum_t id, bmask_t bmask, const char *name);
idaman ssize_t ida_export get_bmask_name(qstring *out, enum_t id, bmask_t bmask);
idaman bool ida_export set_bmask_cmt(enum_t id, bmask_t bmask, const char *cmt, bool repeatable);
idaman ssize_t ida_export get_bmask_cmt(qstring *buf, enum_t id, bmask_t bmask, bool repeatable);
//@}
#endif // _ENUM_HPP