/*
 *      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  ulong 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
extern  netnode 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,ulong *bufsize)       \
        { return (type *)netnode(ea).getblob(buf,bufsize,code,stag); }  \
inline void N_PASTE(set_,name)(ea_t ea,const type *oi,int 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) { return type(netnode(ea).altval(code)-1L); }  \
inline void set(ea_t ea,type x) { netnode(ea).altset(code,x+1L); }      \
inline void del(ea_t ea) { netnode(ea).altdel(code); }

#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_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)
//--------------------------------------------------------------------------

// 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      (-2)    // reserved for enums, see enum.hpp
#define  NALT_WIDE      (-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)

// 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

// 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(ulong ea);
//      void   set_wide_value(ulong ea,ulong x);
//      void   del_wide_value(ulong 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_ULONG (get_strid,_set_strid,_del_strid, NALT_STRUCT)
void set_strid(ulong ea,ulong tid);
void del_strid(ulong ea);

// 'seen' flags (used internally by the kernel)
// Don't use.
NALT_ULONG (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_ULONG (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.
// I decided to create additional flags to keep additional information
// about addresses.
inline void  set_aflags0(ulong ea,ulong flags) { netnode(ea).altset(NALT_AFLAGS,flags); }
inline ulong get_aflags0(ulong ea)             { return netnode(ea).altval(NALT_AFLAGS); }
inline void  del_aflags0(ulong ea)             { netnode(ea).altdel(NALT_AFLAGS); }
idaman void  ida_export set_aflags(ulong ea,ulong flags);
idaman void  ida_export set_abits(ulong ea,ulong bits);
idaman void  ida_export clr_abits(ulong ea,ulong bits);
idaman ulong ida_export get_aflags(ulong ea);
idaman void  ida_export del_aflags(ulong 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

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

#define IMPLEMENT_AFLAG_FUNCTIONS(bit,test,set,clear)                   \
inline bool test(ulong ea)   { return (get_aflags(ea) & bit) != 0; }    \
inline void set(ulong ea)    { set_abits(ea,bit); }                     \
inline void clear(ulong 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)

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); }


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

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

// enum id for the first operand (low level)
// Don't use, see get_enum_id()
NALT_ULONG (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_ULONG (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_ULONG (get_ind_purged,set_ind_purged,del_ind_purged,NALT_PURGE)

// 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)

//----------------------------------------------------------------------
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
{
  ulong table;
  ulong 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)
  ushort ncases;                // number of cases (excluding default)
  ulong jumps;                  // jump table address
  union {
    ulong values;               // values table address
    ulong lowcase;              // the lowest value in cases
  };
  ulong defjump;                // default jump address
  ulong 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_HIGH22 = 7,    // high 22bits of 32bit offset
  REF_LOW10  = 8,    // low  10bits 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
  ulong tdelta;                 // offset from the target
};

#define MAXSTRUCPATH  32        // maximal inclusion depth of unions

struct strpath_t
{
  int len;
  tid_t ids[MAXSTRUCPATH]; // for union member ids
  long 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, ulong 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);


// calculate the target address of a reference
// note: this function may change 'ri' structure.
//       if ri.base is BADADDR, it calculates the offset base address

idaman ea_t ida_export calc_reference_target(ea_t from, refinfo_t &ri, ulong opval);


// calculate the value of the reference base.
// the reference basevalue is used like this:  offset target - reference_basevalue
// usually the basevalue is equal to 0
// if it is not equal to 0, then ri.base contains the address of reference_basevalue
// (which is not equal to reference_basevalue for 16-bit programs!)

idaman ulong ida_export calc_reference_basevalue(ea_t from, refinfo_t &ri, ulong opval, ea_t target);


// the following function retrieves refinfo_t structure and calculates the target

inline ea_t calc_target(ea_t from, ea_t ea, int n, ulong opval)
{
  refinfo_t ri;
  if ( get_refinfo(ea, n, &ri) )
    return calc_reference_target(from, ri, opval);
  return BADADDR;
}


//--------------------------------------------------------------------------
// 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, long delta);
idaman int  ida_export read_struc_path(netnode node, int idx, tid_t *path, long *delta);  // returns plen

#define DEFINE_PATH_FUNCS(name, code)                                \
inline int  N_PASTE(get_,name)(ea_t ea, tid_t *path, long *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, long 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, p_list *fnames); // buffers must be at least MAXSTR
idaman bool ida_export set_ti(ea_t ea, const type_t *ti, const p_list *fnames);
inline void     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, p_list *fnames); // buffers must be at least MAXSTR
idaman bool ida_export set_op_ti(ea_t ea, int n, const type_t *ti, const p_list *fnames);
inline void     del_ti(ea_t ea, int n) { set_op_ti(ea, n, (type_t *)"", NULL); }

#pragma pack(pop)
#endif // NALT_HPP
