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

270 lines
15 KiB
C++

/*
* CPP/D/Swift Demangler.
* Copyright (c) 2000-2018 by Iouri Kharon.
* E-mail: yjh@styx.cabel.net
*
* ALL RIGHTS RESERVED.
*
*/
#ifndef _DEMANGLE_HPP
#define _DEMANGLE_HPP
// int32 result code
#define ME_INTERR -1 // Internal error
#define ME_PARAMERR -2 // Input parameters are wrong
#define ME_ILLSTR -3 // Incorrectly mangled name
#define ME_SMALLANS -4 // Output buffer is too small
// This code is possible only with the 'old' calling
// form. With the new calling form the output buffer
// will have '...' as the last characters and the
// result code or'ed with the sign bit
#define ME_FRAME -5 // Partial demanging is possible (the input name has
// unrecognized suffix)
#define ME_NOCOMP -6 // Could not determine the compiler
#define ME_ERRAUTO -7 // Specified compiler is impossible for the input name
#define ME_NOHASHMEM -8 // Out of internal indexes-most likely bad input name
#define ME_NOSTRMEM -9 // Out of internal buffers (can't be!:)
#define ME_NOERROR_LIMIT -10 // Lowest error number. Lower values
// signal about the truncated output name
// (the output buffer is too small)
#define M_PRCMSK 0x0000000F // If = 0, then data
#define MT_DEFAULT 0x00000001 // 1 - default (for watcom/gnu only this)
#define MT_CDECL 0x00000002 // 2 - __cdecl
#define MT_PASCAL 0x00000003 // 3 - __pascal
#define MT_STDCALL 0x00000004 // 4 - __stdcall
#define MT_FASTCALL 0x00000005 // 5 - __fastcall
#define MT_THISCALL 0x00000006 // 6 - __thiscall [ms & bc => pragma only]
#define MT_FORTRAN 0x00000007 // 7 - __fortran
#define MT_SYSCALL 0x00000008 // 8 - __syscall [without ms]
#define MT_INTERRUPT 0x00000009 // 9 - __interrupt (only with __cdecl!)
#define MT_MSFASTCALL 0x0000000A // A - __msfastcall (bc)
#define MT_CLRCALL 0x0000000B // B - __clrcall (vc7)
#define MT_DMDCALL 0x0000000C // C - __dcall (dm D language abi)
#define MT_VECTORCALL 0x0000000D // D - __vectorcall (vc13)
#define MT_REGCALL 0x0000000E // E - __regcall (icl, clang)
// reserved
#define MT_LOCALNAME 0x0000000F // f - might be function or data. Currently
// is used only for bc - as the
// identifier for local pascal labels
#define M_SAVEREGS 0x00000010 // For functions with "__saveregs"
#define M_CLASS 0x000000E0 // 0 - no keyword (not a member field)
#define MT_PUBLIC 0x00000020 // 1 - public
#define MT_PRIVATE 0x00000040 // 2 - private
#define MT_PROTECT 0x00000060 // 3 - protected
#define MT_MEMBER 0x00000080 // 4 - undetermined (bc/wat/gcc)
#define MT_VTABLE 0x000000A0 // 5 - vtable (bc/gnu)
#define MT_RTTI 0x000000C0 // 6 - typeinfo table (gcc3), witness table (Swift)
// reserved
#define M_PARMSK 0x0000FF00 // Parameter number mask (excluding ellipsis)
// 255 - >= 255
#define MT_PARSHF 8 // shift to PARMSK
#define MT_PARMAX 0xFF // Number limiter
// ATT: when CC is __vectorcall and mode is 'C'
// real argscount is unknown. This number is
// total sizeof of all arguments divided to
// sizeof of defptr
#define M_ELLIPSIS 0x00010000 // The function _certainly_ has '...'
#define MT_VOIDARG 0x0001FF00 // If = 0, the func(void), i.e. no parameters
#define M_STATIC 0x00020000 // static
// gcc3 - static data in a function
// might be encountered in object files and
// (possibly) in binaries with debug info
#define M_VIRTUAL 0x00040000 // virtual
// NOTE: for (D) not virtual -- this (counted!)
#define M_AUTOCRT 0x00080000 // Most likely "autogenerated" function (data)
// NOTE: +M_STATIC => "__linkproc__" (bc)
#define M_TYPMASK 0x00700000 // Special functions (0-regular function)
#define MT_OPERAT 0x00100000 // 1 - operator
#define MT_CONSTR 0x00200000 // 2 - constructor
#define MT_DESTR 0x00300000 // 3 - destructor
#define MT_CASTING 0x00400000 // 4 - type conversion
#define MT_CLRCDTOR 0x00500000 // 5 - delphi2010 CLR ctor/dtor for packages
// reserved
#define M_TRUNCATE 0x00800000 // Name was truncated by the compiler (bc/va)
#define M_THUNK 0x01000000 // [thunk]:
#define M_ANONNSP 0x02000000 // ms => Anonymous Namespace for field
// gc3 => Item placed in Anonymous namespace
// wat => anonymous_enum
// bc => + TMPLNAM = PascalTemplate (for DCC)
// If separate - "automatic" except_t
// from CBuilder for "external" variables
// or a template for global object
// constructor/destructor tables (for CBuilder
// as well)
#define M_TMPLNAM 0x04000000 // ms => template name (?)
// wat =>
// bc => template name => its description table
// gc3 => any template funciton/data
#define M_DBGNAME 0x08000000 // ms => CV:
// wat => xxxx: (T?xxxx-form)
// bc => old pascal format (capitalized)
// gc3 => unicode symbols or 'vendor-extension'
// qualifiers are present
#define M_COMPILER 0x70000000 // Compiler mask (0-unknown)
#define MT_MSCOMP 0x10000000 // 1 - microsoft/symantec
#define MT_BORLAN 0x20000000 // 2 - borland
#define MT_WATCOM 0x30000000 // 3 - watcom
#define MT_OTHER 0x40000000 // 4 - digital mars D language (start: _D)
// - apple Swift language (start: [_]_T)
// !!! The following definitions must be last and in this order!
#define MT_GNU 0x50000000 // 5 - GNU - (over VA for autodetection)
#define MT_GCC3 0x60000000 // 6 - gcc-v3
// In the short form this answer is possible
// for GNU/VA as well, but gcc3 can be
// explicitly requested only with it.
// Autodetection works but not very reliable.
#define MT_VISAGE 0x70000000 // 7 - Visual Age - never autodetected
// In the short form this answer means VA
// or GNU. In the automatic mode GNU will
// be used!
//---------------------------------------------------------------------------
// Flags to inhibit different parts of the demangled name
#define MNG_PTRMSK 0x7 // Memory model mask
// DO NOT change order in this group (PtrType)
#define MNG_DEFNEAR 0x0 // inhibit near, display everything else
#define MNG_DEFNEARANY 0x1 // inhibit near/__ptr64, display everything else
#define MNG_DEFFAR 0x2 // inhibit far, display everything else
#define MNG_NOPTRTYP16 0x3 // inhibit everything (disables vc7-extensions)
#define MNG_DEFHUGE 0x4 // inhibit huge, display everything else
#define MNG_DEFPTR64 0x5 // inhibit __pt64, display everything else
// ATT: in 64bit must be + MNG_NOTYPE|MNG_NOCALLC
#define MNG_DEFNONE 0x6 // display everything
#define MNG_NOPTRTYP 0x7 // inhibit everything
//
#define MNG_NODEFINIT 0x00000008 // Inhibit everything except the main name
// This flag is not recommended
// for __fastcall/__stdcall GCC3 names
// because there is a high probablity of
// incorrect demangling. Use it only when
// you are sure that the input is a
// cygwin/mingw function name
//
#define MNG_NOUNDERSCORE 0x00000010 // Inhibit underscores in __ccall, __pascal... +
#define MNG_NOTYPE 0x00000020 // Inhibit callc&based
#define MNG_NORETTYPE 0x00000040 // Inhibit return type of functions
#define MNG_NOBASEDT 0x00000080 // Inhibit base types
// NOTE: also inhibits "__linkproc__"
// NOTE: -"- 'implicit self types' (Swift)
#define MNG_NOCALLC 0x00000100 // Inhibit __pascal/__ccall/etc
// NOTE: also inhibits "extern (cc)" (D)
#define MNG_NOPOSTFC 0x00000200 // Inhibit postfix const
#define MNG_NOSCTYP 0x00000400 // Inhibit public/private/protected
// NOTE: also inhibits in/out/lazy for args (D)
// NOTE: -"- dynamic/super/override/... (Swift)
#define MNG_NOTHROW 0x00000800 // Inhibit throw description
// NOTE: also inhibits all funcattr (D)
#define MNG_NOSTVIR 0x00001000 // Inhibit "static" & "virtual"
// NOTE: also inhibits (D) top-level procs (<=)
#define MNG_NOECSU 0x00002000 // Inhibit class/struct/union/enum[/D:typedef]
#define MNG_NOCSVOL 0x00004000 // Inhibit const/volatile/restrict
// NOTE: also inhibits __unaligned (vc)
// NOTE: also inhibits transaction_safe(gcc)
// NOTE: also inhibits shared/immutable (D)
// NOTE: also inhibits prefix/postfix/infix/inout (Swift)
#define MNG_NOCLOSUR 0x00008000 // Inhibit __closure for borland
// 'reabstract thunk' description (Swift)
#define MNG_NOUNALG 0x00010000 // Inhibit __unaligned (see NOCSVOL)
// NOTE: also inhibit transaction_safe (see NOCSVOL)
#define MNG_NOMANAGE 0x00020000 // Inhibit __pin/__box/__gc for ms(.net)
// NOTE: also inhibit archetype/witness (Swift)
// NOTE: also ingibit [abi:xxxx] (gcc3)
#define MNG_NOMODULE 0x00040000 // Inhibit module names (Swift)
// 0x00080000
//
#define MNG_SHORT_S 0x00100000 // signed (int) is displayed as s(int)
#define MNG_SHORT_U 0x00200000 // unsigned (int) is displayed as u(int)
#define MNG_ZPT_SPACE 0x00400000 // Display space after comma in the arglist
// NOTE: also spaces in name:type pair (Swift)
// and around Swift return clause ->
#define MNG_DROP_IMP 0x00800000 // Inhibit __declspec(dllimport)
//
// 0x01000000
#define MNG_IGN_ANYWAY 0x02000000 // Ingore '_nn' at the end of name
#define MNG_IGN_JMP 0x04000000 // Ingore 'j_' at the beginning of name
#define MNG_MOVE_JMP 0x08000000 // Move 'j_' prefix to the demangled name
// If both MNG_IGN_JMP and MNG_MOVE_JMP
// are set then move the prefix only if
// the name was not truncated
//
#define MNG_COMPILER_MSK 0x70000000 // Compiler mask (0-autodetect)
#define MNG_SHORT_FORM (MNG_NOTYPE|MNG_NORETTYPE|MNG_NOPOSTFC|MNG_NOPTRTYP \
| MNG_NOSCTYP|MNG_NOTHROW|MNG_NOSTVIR|MNG_NOECSU|MNG_NOCLOSUR \
| MNG_SHORT_U|MNG_DROP_IMP|MNG_NOUNALG|MNG_NOMANAGE \
| MNG_IGN_JMP|MNG_MOVE_JMP|MNG_IGN_ANYWAY)
#define MNG_LONG_FORM (MNG_ZPT_SPACE | MNG_IGN_JMP | MNG_IGN_ANYWAY | MNG_NOPTRTYP)
// The description of the following symbol is in the notes
#define MNG_CALC_VALID (MNG_COMPILER_MSK|MNG_IGN_JMP|MNG_IGN_ANYWAY)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef H2ASH
#if !defined(NO_OBSOLETE_FUNCS) || defined(__DEFINE_DEMANGLE__)
typedef int32 ida_export demangler_t(
char *answer,
uint answer_length,
const char *str,
uint32 disable_mask);
idaman demangler_t demangle;
#endif
// If answer_length == 0 then no demangling is performed neither. The function
// will check if demangling is possible and what compiler is used to mangle
// the name. If the name cannot be demangled then the function will return 0.
// NOTE: the answer MT_MSCOMP+1 means __msfastcall
// (or borland class name with "_4" suffix) and the demangling is possible
// either as MS (__fastcall) or as bc (__msfastcall)
// NOTE: the answer MT_GCC3+1 means POSSIBLE mingw/cygwin with
// __stdcall/__fastcall but it might also mean ms-stdcall.
// In essense it means that the demangler cannot determine the compiler
// precisely.
// It also means that the demangling is possible in the gcc3 mode
// ONLY when the compiler is explicitly set to gcc3 and MNG_NODEFINIT
// bit is not set.
// If answer == NULL then the demangler will return check if the demangling
// is possible and only return the flags.
// In this case answer_length should be enough to hold the demangled name.
// NOTE: If int32(answer_length) < 0 then the demangler will calcuate the
// the number of purged bytes for the given name. In this case
// disable_mask may contain only bits included in MNG_CALC_VALID,
// and -answer_length must be equal to the register size (e.g.
// sizeof(uint16/uint32/uint64)). The value of the register size
// is used to check the numeric value in the ms stdcall/fastcall
// encoding (it is used in the gcc mode too).
// if return value <= 0 - no purged bytes or valid information.
// If (value & 1) != 0 - ms stdcall (definite npurged is value-1.
// If (value & 1) == 0 - 'encoded' counter (not implemented yet).
// If answer != NULL (and answer_length != 0) - perform demangling and fill out.
// NOTE: if int32(answer_length) < 0 then the buffer size will be -answer_length
// but 'answer' is interpreted not as a pointer to the output buffer but
// as a pointer to pointer to the output buffer (char**).
// In this case if the function succeeds,a pointer to the answer end
// will be returned in the pointer (like stpcpy). In this form 'answer'
// cannot be NULL and *(char**)answer cannot be NULL.
// answer_length must be greater than 9 for the 'truncated' answer.
typedef int mangled_name_type_t;
const mangled_name_type_t MANGLED_CODE = 0;
const mangled_name_type_t MANGLED_DATA = 1;
const mangled_name_type_t MANGLED_UNKNOWN = 2;
idaman mangled_name_type_t ida_export get_mangled_name_type(const char *name);
#endif // H2ASH
#endif // _DEMANGLE_HPP