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