/*
 *      Interactive disassembler (IDA).
 *      Copyright (c) 1990-2002 by Ilfak Guilfanov.
 *      ALL RIGHTS RESERVED.
 *                              E-mail: ig@datarescue.com
 *
 */

#ifndef NALT_HPP
#define NALT_HPP
#pragma pack(push, 1)           // IDA uses 1 byte alignments

//
//      This file contains definitions of information kept in netnodes.
//      Each address in the program has a corresponding netnode: netnode(ea)
//      If we have no information about the location, the corresponding
//      netnode is not created.
//      Otherwise we will create a netnode and save information in it.
//      All variable length information (names, comments, offset information, etc)
//      is stored in the netnode.
//      Don't forget that some information is already stored in the flags (bytes.hpp)
//
//      IMPORTANT NOTE:
//      Many of functions in this file are very low level (they are marked
//      as low level functions). Use them only if you can't find higher level
//      function to set/get/del information.
//
//      You can create your own nodes in IDP module and store information
//      in them. Look at netnode.hpp for the definition of netnodes.
//

#include <netnode.hpp>

//--------------------------------------------------------------------------
// Some information is kept in separate netnodes (all these nodes are used
// only by the kernel):

// these nodes keep information about serial autogenerated names,
// like loc_1, loc_2, etc.
extern netnode nmSerEA;     // translation loc(n) -> EA
extern netnode nmSerN;      // translation EA -> n, loc(n)
extern size_t maxSerialName;

idaman netnode ida_export_data net_patch;
                            // node with information about patched bytes
                            // altval(ea)<-(oldval)
                            // charval(ea, 'P')==1 => byte has been patched
idaman netnode ida_export_data import_node;
                            // node with information about imported modules
                            // supval(i) -> module name; altval(i) -> module node
                            // altval(-1) -> number of modules
                            // the module node is:
                            //   supval(ea) -> function name
                            //   altval(ord) -> import ea

//--------------------------------------------------------------------------

// Macro definitions used in this header file (internal)

#define _N_PASTE(x,y)   x ## y
#define N_PASTE(x,y)    _N_PASTE(x,y)
#define NSUP_TYPE(name,type,code,size)                                  \
inline type *N_PASTE(get_,name)(ea_t ea)                                \
        { return (type *)netnode(ea).supval(code); }                    \
inline void N_PASTE(set_,name)(ea_t ea,const type *oi)                  \
        { netnode(ea).supset(code,oi,size); }                           \
inline void N_PASTE(del_,name)(ea_t ea) { netnode(ea).supdel(code); }

#define NSUP_VTYPE(name,type,code)                                      \
inline type *N_PASTE(get_,name)(ea_t ea)                                \
        { return (type *)netnode(ea).supval(code); }                    \
inline void N_PASTE(set_,name)(ea_t ea,const type *oi,int size)         \
        { netnode(ea).supset(code,oi,size); }                           \
inline void N_PASTE(del_,name)(ea_t ea) { netnode(ea).supdel(code); }

#define NSUP_BLOB(name,type,code)                                       \
inline type *N_PASTE(get_,name)(ea_t ea,type *buf,size_t *bufsize)      \
        { return (type *)netnode(ea).getblob(buf,bufsize,code,stag); }  \
inline void N_PASTE(set_,name)(ea_t ea,const type *oi,size_t size)      \
        { netnode(ea).setblob(oi,size,code,stag); }                     \
inline void N_PASTE(del_,name)(ea_t ea) { netnode(ea).delblob(code,stag); }

#define NALT_TYPE(get,set,del,type,code)                                \
inline type get(ea_t ea) { type *x = (type *)netnode(ea).supval(code, atag); return x == NULL ? type(-1) : type(*x-1); } \
inline void set(ea_t ea,type x) { x++; netnode(ea).supset(code, &x, sizeof(x), atag); } \
inline void del(ea_t ea) { netnode(ea).supdel(code, atag); }

#define NSUP_STRUCT(name,code)  NSUP_TYPE(name,N_PASTE(name,_t),code,sizeof(N_PASTE(name,_t)))
#define NSUP_STRING(name,code)  NSUP_TYPE(name,char,code,0)
#define NSUP_VAR(name,code,t)   NSUP_VTYPE(name,t,code)
#define NALT_EA(    get,set,del,code) NALT_TYPE(get,set,del,ea_t,  code)
#define NALT_ULONG( get,set,del,code) NALT_TYPE(get,set,del,ulong, code)
#define NALT_USHORT(get,set,del,code) NALT_TYPE(get,set,del,ushort,code)
#define NALT_UCHAR( get,set,del,code) NALT_TYPE(get,set,del,uchar, code)
//--------------------------------------------------------------------------

// Structure of altvals array of netnode(ea)
// altvals is a virtual array of 32-bit longs attached to a netnode.
// size of this array is unlimited. Unused indexes are not kept in the
// database. We use only first several indexes to this array:

#define  NALT_ENUM      uval_t(-2)// reserved for enums, see enum.hpp
#define  NALT_WIDE      uval_t(-1)// 16-bit byte value
//#define  NALT_OBASE0    1       // offset base 1
//#define  NALT_OBASE1    2       // offset base 2
#define  NALT_STRUCT    3         // struct id
#define  NALT_SEENF     4         // 'seen' flag (used in structures)
//#define  NALT_OOBASE0   5       // outer offset base 1
//#define  NALT_OOBASE1   6       // outer offset base 2
#define  NALT_XREFPOS   7         // saved xref address in the xrefs window
#define  NALT_AFLAGS    8         // additional flags for an item
#define  NALT_LINNUM    9         // source line number
#define  NALT_ABSBASE  10         // absolute segment location
#define  NALT_ENUM0    11         // enum id for the first operand
#define  NALT_ENUM1    12         // enum id for the second operand
//#define  NALT_STROFF0  13       // struct offset, struct id for the first operand
//#define  NALT_STROFF1  14       // struct offset, struct id for the second operand
#define  NALT_PURGE    15         // number of bytes purged from the stack
                                  // when a function is called indirectly
#define  NALT_STRTYPE  16         // type of string item
#define  NALT_ALIGN    17         // alignment value if the item is FF_ALIGN
                                  // (should by equal to power of 2)
//#define  NALT_HIGH0    18       // linear address of byte referenced by
//                                // high 16 bits of an offset (FF_0HIGH)
//#define  NALT_HIGH1    19       // linear address of byte referenced by
//                                // high 16 bits of an offset (FF_1HIGH)
#define  NALT_COLOR    20         // instruction/data background color

// Structure of supvals array of netnode(ea)
// Supvals is a virtual array of objects of arbitrary length attached
// to a netnode (length of one element is limited by MAXSPECSIZE, though)
// We use first several indexes to this array:

#define  NSUP_CMT       0       // regular comment
#define  NSUP_REPCMT    1       // repeatable comment
#define  NSUP_FOP1      2       // forced operand 1
#define  NSUP_FOP2      3       // forced operand 2
#define  NSUP_JINFO     4       // jump table info
#define  NSUP_ARRAY     5       // array parameters
#define  NSUP_OMFGRP    6       // OMF: group of segments (not used anymore)
#define  NSUP_FOP3      7       // forced operand 3
#define  NSUP_SWITCH    8       // switch information
#define  NSUP_REF0      9       // complex reference information for operand 1
#define  NSUP_REF1      10      // complex reference information for operand 2
#define  NSUP_REF2      11      // complex reference information for operand 3
#define  NSUP_OREF0     12      // outer complex reference information for operand 1
#define  NSUP_OREF1     13      // outer complex reference information for operand 2
#define  NSUP_OREF2     14      // outer complex reference information for operand 3
#define  NSUP_STROFF0   15      // stroff: struct path for the first operand
#define  NSUP_STROFF1   16      // stroff: struct path for the second operand
#define  NSUP_SEGTRANS  17      // segment translations
#define  NSUP_FOP4      18      // forced operand 4
#define  NSUP_FOP5      19      // forced operand 5
#define  NSUP_FOP6      20      // forced operand 6
#define  NSUP_REF3      21      // complex reference information for operand 4
#define  NSUP_REF4      22      // complex reference information for operand 5
#define  NSUP_REF5      23      // complex reference information for operand 6
#define  NSUP_OREF3     24      // outer complex reference information for operand 4
#define  NSUP_OREF4     25      // outer complex reference information for operand 5
#define  NSUP_OREF5     26      // outer complex reference information for operand 6

// values E_PREV..E_NEXT+1000 are reserved (1000..2000..3000 decimal)

// values NSUP_POINTS..NSUP_POINTS+0x1000 are reserved
#define  NSUP_POINTS    0x1000  // SP change points blob (see funcs.cpp)

// values NSUP_MANUAL..NSUP_MANUAL+0x1000 are reserved
#define  NSUP_MANUAL    0x2000  // manual instruction

// values NSUP_TYPEINFO..NSUP_TYPEINFO+0x1000 are reserved
#define  NSUP_TYPEINFO  0x3000  // type information

// values NSUP_REGVAR..NSUP_REGVAR+0x1000 are reserved
#define  NSUP_REGVAR    0x4000  // register variables

// values NSUP_LLABEL..NSUP_LLABEL+0x1000 are reserved
#define  NSUP_LLABEL    0x5000  // local labels

// values NSUP_REGARG..NSUP_REGARG+0x1000 are reserved
#define  NSUP_REGARG    0x6000  // register argument type/name descriptions

// values NSUP_FTAILS..NSUP_FTAILS+0x1000 are reserved
#define  NSUP_FTAILS    0x7000  // function tails or tail referers

// Tag values to store xrefs (see cref.cpp)
#define NALT_CREF_TO         'X'     // code xref to...
#define NALT_CREF_FROM       'x'     // code xref from...
#define NALT_DREF_TO         'D'     // data xref to...
#define NALT_DREF_FROM       'd'     // data xref from...

//--------------------------------------------------------------------------
//      C O N V E N I E N C E   F U N C T I O N S
//--------------------------------------------------------------------------

// up to 32bit value for wide (more than 8-bit) byte processors
// (low level functions, see bytes.hpp for higher level functions)
// this macro will generate functions
//      ulong  get_wide_value(ea_t ea);
//      void   set_wide_value(ea_t ea,ulong x);
//      void   del_wide_value(ea_t ea);
// Don't use, look at: get_full_byte(), get_full_word(), get_full_long()
NALT_ULONG(get_wide_value,set_wide_value,del_wide_value,NALT_WIDE)

// Structure ID for structures in structure definitions.
// Don't use, see: get_typeinfo()
NALT_EA(get_strid,_set_strid,_del_strid, NALT_STRUCT)
void set_strid(ea_t ea, tid_t tid);
void del_strid(ea_t ea);

// 'seen' flags (used internally by the kernel)
// Don't use.
NALT_UCHAR(get_seenf,  set_seenf,   del_seenf,   NALT_SEENF)


// position of cursor in the window with cross-references to the address
// Used by the user-interface.
NALT_EA(get_xrefpos, set_xrefpos, del_xrefpos, NALT_XREFPOS)

// Additional flags for the location.
// All 32-bits of the main flags (see bytes.hpp) are used up.
// Additional flags keep more information about addresses.
// DO NOT use these flags directly unless there is absoletely no way.
// They are too low level and may corrupt the database.
inline void  set_aflags0(ea_t ea, ulong flags) { netnode(ea).altset(NALT_AFLAGS,flags); }
inline ulong get_aflags0(ea_t ea)              { return flags_t(netnode(ea).altval(NALT_AFLAGS)); }
inline void  del_aflags0(ea_t ea)              { netnode(ea).altdel(NALT_AFLAGS); }
idaman void  ida_export set_aflags(ea_t ea, ulong flags);
idaman void  ida_export set_abits(ea_t ea,ulong bits);
idaman void  ida_export clr_abits(ea_t ea,ulong bits);
idaman ulong ida_export get_aflags(ea_t ea);
idaman void  ida_export del_aflags(ea_t ea);

#define AFL_LINNUM      0x00000001L     // has line number info
#define AFL_USERSP      0x00000002L     // user-defined SP value
#define AFL_PUBNAM      0x00000004L     // name is public (inter-file linkage)
#define AFL_WEAKNAM     0x00000008L     // name is weak
#define AFL_HIDDEN      0x00000010L     // the item is hidden completely
#define AFL_MANUAL      0x00000020L     // the instruction/data is specified by the user
#define AFL_NOBRD       0x00000040L     // the code/data border is hidden
#define AFL_ZSTROFF     0x00000080L     // display struct field name at 0 offset
                                        // when displaying an offset. example:
                                        //   offset somestruct.field_0
                                        // if this flag is clear, then
                                        //   offset somestruct
#define AFL_BNOT0       0x00000100L     // the 1st operand is bitwise negated
#define AFL_BNOT1       0x00000200L     // the 2nd operand is bitwise negated
#define AFL_LIB         0x00000400L     // item from the standard library
                                        // low level flag, is used to set
                                        // FUNC_LIB of func_t
#define AFL_TI          0x00000800L     // has typeinfo? (NSUP_TYPEINFO)
#define AFL_TI0         0x00001000L     // has typeinfo for operand 0? (NSUP_TYPEINFO+1)
#define AFL_TI1         0x00002000L     // has typeinfo for operand 1? (NSUP_TYPEINFO+2)
#define AFL_LNAME       0x00004000L     // has local name too (FF_NAME should be set)
#define AFL_TILCMT      0x00008000L     // has type comment? (such a comment
                                        // may be changed by IDA)
#define AFL_LZERO0      0x00010000L     // toggle leading zeroes for the 1st operand
#define AFL_LZERO1      0x00020000L     // toggle leading zeroes for the 2nd operand
#define AFL_COLORED     0x00040000L     // has user defined instruction color?
#define AFL_TERSESTR    0x00080000L     // terse structure variable display?
#define AFL_SIGN0       0x00100000L     // code: toggle sign of the 1st operand
#define AFL_SIGN1       0x00200000L     // code: toggle sign of the 2nd operand

// The following macro is used to define 3 functions to work with a bit:
//      int  test(ea_t ea);    - test if the bit is set
//      void set(ea_t ea);     - set bit
//      void clear(ea_t ea);   - clear bit

#define IMPLEMENT_AFLAG_FUNCTIONS(bit,test,set,clear)                  \
inline bool test(ea_t ea)   { return (get_aflags(ea) & bit) != 0; }    \
inline void set(ea_t ea)    { set_abits(ea,bit); }                     \
inline void clear(ea_t ea)  { clr_abits(ea,bit); }


IMPLEMENT_AFLAG_FUNCTIONS(AFL_HIDDEN,  is_hidden_item,hide_item,unhide_item)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_NOBRD,   is_hidden_border,hide_border,unhide_border)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_ZSTROFF, is_zstroff,set_zstroff,clr_zstroff)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_BNOT0,   is__bnot0,set__bnot0,clr__bnot0)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_BNOT1,   is__bnot1,set__bnot1,clr__bnot1)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_LIB,     is_libitem,set_libitem,clr_libitem)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_TI,      has_ti,set_has_ti,clr_has_ti)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_TI0,     has_ti0,set_has_ti0,clr_has_ti0)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_TI1,     has_ti1,set_has_ti1,clr_has_ti1)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_LNAME,   has_lname,set_lname_bit,clr_lname_bit)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_TILCMT,  is_tilcmt,set_tilcmt,clr_tilcmt)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_USERSP,  is_usersp,set_usersp,clr_usersp)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_LZERO0,  is_lzero0,set_lzero0,clr_lzero0)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_LZERO1,  is_lzero1,set_lzero1,clr_lzero1)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_COLORED, is_colored_item,set_colored_item,clr_colored_item)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_TERSESTR,is_terse_struc,set_terse_struc,clr_terse_struc)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_SIGN0,   is__invsign0,set__invsign0,clr__invsign0)
IMPLEMENT_AFLAG_FUNCTIONS(AFL_SIGN1,   is__invsign1,set__invsign1,clr__invsign1)

inline void set_visible_item(ea_t ea, bool visible)
{
  if ( visible )
     unhide_item(ea);
  else
      hide_item(ea);
}

inline bool is_visible_item(ea_t ea) { return !is_hidden_item(ea); }

inline bool is_finally_visible_item(ea_t ea) // is instruction visible?
 { return (inf.s_cmtflg & SW_SHHID_ITEM) != 0 || is_visible_item(ea); }


// source line numbers (they are sometimes present in object files)
// Thes functions may be used if necessary.
NALT_EA(get_linnum0,set_linnum0, del_linnum0, NALT_LINNUM)
idaman void   ida_export set_source_linnum(ea_t ea, uval_t lnnum);
idaman uval_t ida_export get_source_linnum(ea_t ea);      // returns BADADDR if no lnnum
idaman void   ida_export del_source_linnum(ea_t ea);

// absolute segment base address
// These functions may be used if necessary.
NALT_EA(get_absbase,set_absbase, del_absbase, NALT_ABSBASE)

// enum id for the first operand (low level)
// Don't use, see get_enum_id()
NALT_EA(get_enum_id0,set_enum_id0,del_enum_id0,NALT_ENUM0)

// enum id for the second operand (low level)
// Don't use, see get_enum_id()
NALT_EA(get_enum_id1,set_enum_id1,del_enum_id1,NALT_ENUM1)

// number of bytes purged from the stack when a function is called indirectly
// These functions may be used if necessary.
NALT_EA(get_ind_purged,set_ind_purged,del_ind_purged,NALT_PURGE)
bool set_purged(ea_t ea, int value); // use this instead of set_ind_purged

// type of string
// Don't use, see: get_typeinfo()
NALT_ULONG(get_str_type,set_str_type,del_str_type,NALT_STRTYPE)

inline char get_str_type_code(ulong strtype) { return char(strtype); }

#define ASCSTR_C        ASCSTR_TERMCHR // C-style ASCII string
#define ASCSTR_TERMCHR  0       // Character-terminated ASCII string
                                // The termination characters are kept in
                                // the next bytes of string type
inline char get_str_term1(long strtype) { return char(strtype>>8); }
inline char get_str_term2(long strtype) { return char(strtype>>16); }
                                // if the second termination character is
                                // '\0', then it doesn't exist.
#define ASCSTR_PASCAL   1       // Pascal-style ASCII string (length byte)
#define ASCSTR_LEN2     2       // Pascal-style, length is 2 bytes
#define ASCSTR_UNICODE  3       // Unicode string
#define ASCSTR_LEN4     4       // Pascal-style, length is 4 bytes
#define ASCSTR_ULEN2    5       // Pascal-style Unicode, length is 2 bytes
#define ASCSTR_ULEN4    6       // Pascal-style Unicode, length is 4 bytes
#define ASCSTR_LAST     6       // Last string type

inline bool is_unicode(long strtype)
{
  char code = get_str_type_code(strtype);
  return code == ASCSTR_UNICODE
      || code == ASCSTR_ULEN2
      || code == ASCSTR_ULEN4;
}

inline bool is_pascal(long strtype)
{
  char code = get_str_type_code(strtype);
  return code == ASCSTR_PASCAL
      || code == ASCSTR_LEN2
      || code >= ASCSTR_LEN4;
}


// alignment value (should be power of 2)
// These functions may be used if necessary.
NALT_ULONG(get_alignment,set_alignment,del_alignment,NALT_ALIGN)

// instruction/data background color
NALT_ULONG(_get_item_color,_set_item_color,_del_item_color,NALT_COLOR)
idaman void      ida_export set_item_color(ea_t ea, bgcolor_t color);
idaman bgcolor_t ida_export get_item_color(ea_t ea);      // returns DEFCOLOR if no color
idaman void      ida_export del_item_color(ea_t ea);

//----------------------------------------------------------------------
NSUP_STRING(nalt_cmt,NSUP_CMT)          // regular comment       (low level, don't use)
NSUP_STRING(nalt_rptcmt,NSUP_REPCMT)    // repeatable comment    (low level, don't use)
NSUP_STRING(fop1,NSUP_FOP1)             // first forced operand  (low level, don't use)
NSUP_STRING(fop2,NSUP_FOP2)             // second forced operand (low level, don't use)
NSUP_STRING(fop3,NSUP_FOP3)             // third forced operand  (low level, don't use)
NSUP_STRING(fop4,NSUP_FOP4)             // 4 forced operand      (low level, don't use)
NSUP_STRING(fop5,NSUP_FOP5)             // 5 forced operand      (low level, don't use)
NSUP_STRING(fop6,NSUP_FOP6)             // 6 forced operand      (low level, don't use)
NSUP_BLOB(manual_insn0,char,NSUP_MANUAL)// manual instruction    (low level, don't use)

//--------------------------------------------------------------------------
struct jumptable_info_t
{
  ea_t table;
  asize_t size;
};
NSUP_STRUCT(jumptable_info,NSUP_JINFO)  // information about jump tables

//--------------------------------------------------------------------------
struct array_parameters_t
{
  long flags;
#define AP_ALLOWDUPS    0x00000001L     // use 'dup' construct
#define AP_SIGNED       0x00000002L     // treats numbers as signed
#define AP_INDEX        0x00000004L     // display array element indexes as comments
  long lineitems;                       // number of items on a line
  long alignment;                       // -1 - don't align
                                        // 0  - align automatically
                                        // else item width
};
NSUP_STRUCT(array_parameters,NSUP_ARRAY)

//--------------------------------------------------------------------------
struct switch_info_t {
  ushort flags;
#define SWI_SPARSE      0x01    // sparse switch (value table present)
                                // otherwise lowcase present
#define SWI_V32         0x02    // 32-bit values in table
#define SWI_J32         0x04    // 32-bit jump offsets
#define SWI_VSPLIT      0x08    // value table is split
#define SWI_DEFAULT     0x10    // default case present
#define SWI_END_IN_TBL  0x20    // switchend in table (last entry)
#define SWI_JMP_INV     0x40    // jumptable is inversed (last entry is
                                // for first entry in values table)
#define SWI_SHIFT1      0x80    // use formula (element*2 + pc)
                                // to find jump targets
  ushort ncases;                // number of cases (excluding default)
  ea_t jumps;                   // jump table address
  union
  {
    ea_t values;                // values table address
    uval_t lowcase;             // the lowest value in cases
  };
  ea_t defjump;                 // default jump address
  ea_t startea;                 // start of switch idiom
};

NSUP_STRUCT(switch_info,NSUP_SWITCH)

//--------------------------------------------------------------------------
//
//      References are represented in the following form:
//
//              target + tdelta - base
//
//      If the target is not present, then it will be calculated using
//
//              target = operand_value - tdelta + base
//
//      The target must be present for LOW and HIGH reference types

typedef uchar reftype_t;
const reftype_t                  // type of reference
  REF_OFF8   = 0,    // 8bit full offset
  REF_OFF16  = 1,    // 16bit full offset
  REF_OFF32  = 2,    // 32bit full offset
  REF_LOW8   = 3,    // low 8bits of 16bit offset
  REF_LOW16  = 4,    // low 16bits of 32bit offset
  REF_HIGH8  = 5,    // high 8bits of 16bit offset
  REF_HIGH16 = 6,    // high 16bits of 32bit offset
  REF_VHIGH  = 7,    // high ph.high_fixup_bits of 32bit offset
  REF_VLOW   = 8,    // low  ph.high_fixup_bits of 32bit offset
  REF_OFF64  = 9,    // 64bit full offset
  REF_LAST = REF_OFF64;

struct refinfo_t                // information about a reference
{
  reftype_t type;               // type of reference
  int target_present;           // is the reference target specified?
  ea_t target;                  // reference target
  ea_t base;                    // base of reference
  adiff_t tdelta;               // offset from the target
};

#define MAXSTRUCPATH  32        // maximal inclusion depth of unions

// Information for structure offsets.
// ids[0] contains the id of the structure.
// ids[1..len-1] contain ids of the structure members used in the structure offset
// expression.
// len is the length of the path, i.e. the number of elements in 'ids'
struct strpath_t
{
  int len;
  tid_t ids[MAXSTRUCPATH]; // for union member ids
  adiff_t delta;
};

struct enum_const_t
{
  tid_t tid;
  uchar serial;
};

union typeinfo_t        // additional information about a data type
{
  refinfo_t ri;         // for offset members
  tid_t tid;            // for struct, etc. members
  strpath_t path;       // for stroff
  long strtype;         // for strings (ASCSTR_...)
  enum_const_t ec;      // for enums
};

// n may be 0, 1, 2, OPND_MASK
// OPND_OUTER may be used too
// Don't use these functions, see get_typeinfo(), set_typeinfo()

idaman int ida_export set_refinfo_ex(ea_t ea, int n, const refinfo_t *ri);  // 1-ok, 0-bad refinfo
idaman int ida_export set_refinfo(ea_t ea, int n,
          reftype_t type, ea_t target=BADADDR, ea_t base=0, adiff_t tdelta=0);
idaman int ida_export get_refinfo(ea_t ea, int n, refinfo_t *ri);        // 1-ok, 0-no refinfo
idaman int ida_export del_refinfo(ea_t ea, int n);


//--------------------------------------------------------------------------
// structure pathes for unions and structures with unions (strpath)

// a structure path is an array of id's.
// the first id is the id of the structure itself
// additional id's (if any) specify which member of a union we should select
// the maximal size of array is MAXSTRUCPATH
// strpaths are used to determine how to display structure offsets

idaman void ida_export write_struc_path(netnode node, int idx, const tid_t *path, int plen, adiff_t delta);
idaman int  ida_export read_struc_path(netnode node, int idx, tid_t *path, adiff_t *delta);  // returns plen

#define DEFINE_PATH_FUNCS(name, code)                                \
inline int  N_PASTE(get_,name)(ea_t ea, tid_t *path, adiff_t *delta) \
 { return read_struc_path(netnode(ea), code, path, delta); }         \
inline void N_PASTE(set_,name)(ea_t ea, const tid_t *path, int plen, adiff_t delta) \
 { write_struc_path(netnode(ea), code, path, plen, delta); }         \
inline void N_PASTE(del_,name)(ea_t ea)                              \
 { netnode(ea).supdel(code); }

DEFINE_PATH_FUNCS(stroff0, NSUP_STROFF0)
DEFINE_PATH_FUNCS(stroff1, NSUP_STROFF1)

//--------------------------------------------------------------------------
// low level segment translation functions
// please use function from segment.hpp
NSUP_VAR(_segtrans, NSUP_SEGTRANS, ea_t)

//--------------------------------------------------------------------------
// type information (ti) storage
// ti is stored for the following objects:
//             object                where
//       --------------------   ---------------
//       function                 NSUP_TYPEINFO
//       data                     NSUP_TYPEINFO
//       operand                  NSUP_TYPEINFO+1+number_of_operand(0..n)
//
// up to 256 operands are supported for ti.

typedef uchar type_t;
typedef uchar p_list;

// work with function/data types
// These functions may be used if necessary.
idaman bool ida_export get_ti(ea_t ea, type_t *buf, size_t bufsize, p_list *fnames, size_t fnsize);
idaman bool ida_export set_ti(ea_t ea, const type_t *ti, const p_list *fnames);
inline void idaapi del_ti(ea_t ea) { set_ti(ea, (type_t *)"", NULL); }

// work with operand types
// These functions may be used if necessary.
idaman bool ida_export get_op_ti(ea_t ea, int n, type_t *buf, size_t bufsize, p_list *fnames, size_t fnsize);
idaman bool ida_export set_op_ti(ea_t ea, int n, const type_t *ti, const p_list *fnames);
inline void idaapi del_ti(ea_t ea, int n) { set_op_ti(ea, n, (type_t *)"", NULL); }

//------------------------------------------------------------------------//
// Rootnode indexes:

// supvals
#define RIDX_FILE_FORMAT_NAME        1  // file format name for loader modules
#define RIDX_SELECTORS               2  // 2..63 are for selector_t blob (see init_selectors())
#define RIDX_GROUPS                 64  // segment group information (see init_groups())
#define RIDX_H_PATH                 65  // C header path
#define RIDX_C_MACROS               66  // C predefined macros
#define RIDX_SMALL_IDC              67  // Instant IDC statements
#define RIDX_NOTEPAD                68  // notepad blob, occupies 1000 indexes (1MB of text)
#define RIDX_INCLUDE              1100  // assembler include file name

// altvals
#define RIDX_ALT_VERSION        uval_t(-1) // initial version of database
#define RIDX_ALT_CTIME          uval_t(-2) // database creation timestamp
#define RIDX_ALT_ELAPSED        uval_t(-3) // seconds database stayed open
#define RIDX_ALT_NOPENS         uval_t(-4) // how many times the database is opened
#define RIDX_ALT_CRC32          uval_t(-5) // input file crc32

//--------------------------------------------------------------------------
// Get name of the input file

inline char *idaapi get_input_file_path(void) { return RootNode.value(); } // full path
idaman char *ida_export get_root_filename(void);     // file name only
inline void set_root_filename(const char *file) { RootNode.set(file); }

// get input file crc32 stored in the database
// it can be used to check that the input file has not been changed
inline ulong idaapi retrieve_input_file_crc32(void) { return ulong(RootNode.altval(RIDX_ALT_CRC32)); }

// Get/Set name of the include file
inline char *idaapi get_asm_inc_file(void) { return RootNode.supval(RIDX_INCLUDE); }
inline void idaapi set_asm_inc_file(const char *file) { RootNode.supset(RIDX_INCLUDE, file); }

#ifndef BYTES_SOURCE    // undefined bit masks so no one can use them directly
#undef AFL_LINNUM
#undef AFL_USERSP
#undef AFL_PUBNAM
#undef AFL_WEAKNAM
#undef AFL_HIDDEN
#undef AFL_MANUAL
#undef AFL_NOBRD
#undef AFL_ZSTROFF
#undef AFL_BNOT0
#undef AFL_BNOT1
#undef AFL_LIB
#undef AFL_TI
#undef AFL_TI0
#undef AFL_TI1
#undef AFL_LNAME
#undef AFL_TILCMT
#undef AFL_LZERO0
#undef AFL_LZERO1
#undef AFL_COLORED
#undef AFL_TERSESTR
#undef AFL_SIGN0
#undef AFL_SIGN1
#endif

#pragma pack(pop)
#endif // NALT_HPP
