C++ Name-Mangling技术

C++ Name Mangling/Demangling

Standard C++ Example

The Annotated C++ Reference Manual documents one name mangling scheme.
reference:http://www.kegel.com/mangle.html
          http://en.wikipedia.org/wiki/Name_mangling

Gnu C++

The name mangling scheme seems to be based on the one in the C++ Reference Manual, and is partly documented at http://www.delorie.com/gnu/docs/gcc/gxxint_15.html. Code to implement demangling is part of the GNU Binutils package; see libiberty/cplus-dem.c and include/demangle.h.

Microsoft C++

Microsoft uses a proprietary name mangling scheme in its C++ compilers (naturally). The function UnDecorateSymbolName() is provided to map mangled names back to human-readable ones. For examples, see http://www.microsoft.com/library/images/msdn/library/periodic/periodic/msj/hood897.htm, http://microsoft.com/msj/0897/hood0897textfigs.htm or http://www.mvps.org/win32/misc/stackwalk.html
however, there is no documentation on the mangling or unmangling algorithm, beyond a few notes on calling conventions.

See also Wine's debugger sources (e.g. debugger/msc.c. (Link added 30 April 2000)

Preliminary Notes

These are surely inaccurate, but it's a start. Mangled function names have the following pieces, in order:
  1. a prefix of '?'
  2. the function's name (ignoring any class). Operators, constructors, and destructors are represented by two-character codes; see below.
  3. If the function is not an operator, the separator '@' terminates the function name.
  4. If the name is qualified by a class name:
    1. For each qualifying class name from inner to outer, the encoded class name followed by the separator '@'.
    2. the separator '@'
    3. the value "Q"
    else
    1. the separator '@'
    2. the value "Y"
  5. the encoded function calling convention
  6. the encoded signature of the function's return value
  7. the encoded signature of the function's arguments
  8. a suffix of 'Z'

Grammar

Here's another shot at a grammar for names mangled by Visual C++, in a different style:
MangledName:
'?' BasicName Qualification '@' QualifiedTypeCode StorageClass
'?' BasicName '@' UnqualifiedTypeCode StorageClass

BasicName:
'?' operatorCode
string '@'

Qualification:
( string '@' )*

QualifiedTypeCode:
'Q' FunctionTypeCode
'2' DataTypeCode

UnqualifiedTypeCode:
'Y' FunctionTypeCode
'3' DataTypeCode

StorageClass:
'A' (Normal Storage)
'B' (Volatile Storage)
'C' (Const Storage)
'Z' (Executable Storage)

FunctionTypeCode:
CallingConvention ReturnValueTypeCode ArgumentList

Operators

Operator names are represented by a question mark followed by a single character rather than being spelled out. Examples:
myclass::myclass          ?0
myclass::~myclass ?1
myclass::operator new ?2
myclass::operator delete ?3
myclass::operator= ?4
myclass::operator+ ?H
myclass::operator++ ?E

Attributes

These appear immediately before the type they modify.
volatile ?C
const ?B

Function Calling Convention Codes

  • __cdecl -> "A"
  • __fastcall -> "I"
  • __stdcall -> "G"

Function Argument Type Lists

Function arguments types are listed left to right using the following codes. If the parameter list is not void and does not end in elipsis, its encoding is terminated by an @.

Data Type Codes

signed char    C
char D
unsigned char E
short F
unsigned short G
int H
unsigned int I
long J
unsigned long K
float M
double N
long double O
pointer P (see below)
array Q (see below)
struct/class V (see below)
void X (terminates argument list)
elipsis Z (terminates argument list)

Function Pointers

Here's a few examples that tease out how function pointers work:
typedef int (*x)(int); typedef int (*y)(short);
int Fx_i(x fnptr) ?Fx_i@@YAHP6AHH@Z@Z
int Fxix_i(x fnptr, int i, x fnptr3) ?Fxix_i@@YAHP6AHH@ZH0@Z
int Fxx_i(x fnptr, x fnptr2) ?Fxx_i@@YAHP6AHH@Z0@Z
int Fxxi_i(x fnptr, x fnptr2, x fnptr3, int i) ?Fxxi_i@@YAHP6AHH@Z00H@Z
int Fxxx_i(x fnptr, x fnptr2, x fnptr3) ?Fxxx_i@@YAHP6AHH@Z00@Z
int Fxyxy_i(x fnptr, y fnptr2, x fnptr3, y fnptr4) ?Fxyxy_i@@YAHP6AHH@ZP6AHF@Z01@Z
the signature of the arguments of Fxxxi_i() is P6AHH@Z, 0, 0, H, @ Possibly this is interpreted as follows:
  1. P6 = function pointer
    1. A = __cdecl
    2. H = returns int
    3. H = argument int
    4. @ = end of argument list
    5. Z = end of signature
  2. 0 (zero) = repeat first type
  3. 0 (zero) = repeat first type
  4. H = argument int
  5. @ = end of argument list
The signature of the arguments of Fxix_i, i.e. (x fnptr, int i, y fnptr2) is "P6AHH@Z, H, 0, @", and the signature of the arguments of Fxyxy_i, i.e. (x fnptr, y fnptr2, x fnptr3, y fnptr4), is "P6AHH@Z, P6AHF@Z, 0, 1, @". Apparantly digits refer back to types referenced previously in this definition; 0 (zero) refers to the first type, and 1 (one) refers back to the second type.

Classes

void Fmyclass_v(myclass m) ?Fmyclass_v@@YAXVmyclass@@@Z
void Fmxmx_v(myclass arg1, x arg2, myclass arg3, x arg4) ?Fmxmx_v@@YAXVmyclass@@P6AHH@Z01@Z
The signature of an argument list (myclass m) is Vmyclass@@@, which breaks down as follows: means
  1. V = class
  2. class name
  3. @@ = end of class name
  4. @ = end of argument list
The signature of an argument list (myclass arg1, x arg2, myclass arg3, x arg4) is Vmyclass@@P6AHH@Z01@, which breaks down as follows:
  1. V = class
  2. class name
  3. @@ = end of class name
  4. P6AHH@Z = signature of x
  5. 0 = refer back to first type
  6. 1 = refer back to second type
  7. @ = end of argument list
As above, digits refer back to types defined previously.

Examples

Using a simple C++ source file and a perl script, the mangled names for a few functions were generated using Visual C++ 4.2. (The functions were named using something like the mangling scheme in "The Annotated C++ Reference Manual", just for grins.)
typedef int (*x)(int); typedef int (*y)(short);
static int myclass::myStaticMember?myStaticMember@myclass@@2HA
const int myclass::myconstStaticMember?myconstStaticMember@myclass@@2HB
volatile int myclass::myvolatileStaticMember?myvolatileStaticMember@myclass@@2HC
x myfnptr;?myfnptr@@3P6AHH@ZA
int myglobal;?myglobal@@3HA
volatile int myvolatile;?myvolatile@@3HC
int myarray[10];?myarray@@3PAHA
void **Fv_PPv(void) ?Fv_PPv@@YAPAPAXXZ
void *Fv_Pv(void) ?Fv_Pv@@YAPAXXZ
int FA10_i_i(int a[10]) ?FA10_i_i@@YAHQAH@Z
int FPi_i(int *a) ?FPi_i@@YAHPAH@Z
int Fc_i(char bar) ?Fc_i@@YAHD@Z
int Ff_i(float bar) ?Ff_i@@YAHM@Z
int Fg_i(double bar) ?Fg_i@@YAHN@Z
int Fi_i(int bar) ?Fi_i@@YAHH@Z
int Fie_i(int bar, ...) ?Fie_i@@YAHHZZ
int Fii_i(int bar, int goo) ?Fii_i@@YAHHH@Z
int Fiii_i(int bar, int goo, int hoo) ?Fiii_i@@YAHHHH@Z
void Fmxmx_v(myclass arg1, x arg2, myclass arg3, x arg4) ?Fmxmx_v@@YAXVmyclass@@P6AHH@Z01@Z
void Fmyclass_v(myclass m) ?Fmyclass_v@@YAXVmyclass@@@Z
const int Fv_Ci(void) ?Fv_Ci@@YA?BHXZ
long double Fv_Lg(void) ?Fv_Lg@@YAOXZ
int& Fv_Ri(void) ?Fv_Ri@@YAAAHXZ
signed char Fv_Sc(void) ?Fv_Sc@@YACXZ
unsigned char Fv_Uc(void) ?Fv_Uc@@YAEXZ
unsigned int Fv_Ui(void) ?Fv_Ui@@YAIXZ
unsigned long Fv_Ul(void) ?Fv_Ul@@YAKXZ
unsigned short Fv_Us(void) ?Fv_Us@@YAGXZ
volatile int Fv_Vi(void) ?Fv_Vi@@YA?CHXZ
char Fv_c(void) ?Fv_c@@YADXZ
float Fv_f(void) ?Fv_f@@YAMXZ
double Fv_g(void) ?Fv_g@@YANXZ
int Fv_i(void) ?Fv_i@@YAHXZ
long Fv_l(void) ?Fv_l@@YAJXZ
short Fv_s(void) ?Fv_s@@YAFXZ
void Fv_v(void) ?Fv_v@@YAXXZ
void __cdecl Fv_v_cdecl(void) ?Fv_v_cdecl@@YAXXZ
void __fastcall Fv_v_fastcall(void) ?Fv_v_fastcall@@YIXXZ
void __stdcall Fv_v_stdcall(void) ?Fv_v_stdcall@@YGXXZ
int Fx_i(x fnptr) ?Fx_i@@YAHP6AHH@Z@Z
int Fxix_i(x fnptr, int i, x fnptr3) ?Fxix_i@@YAHP6AHH@ZH0@Z
int Fxx_i(x fnptr, x fnptr2) ?Fxx_i@@YAHP6AHH@Z0@Z
int Fxxi_i(x fnptr, x fnptr2, x fnptr3, int i) ?Fxxi_i@@YAHP6AHH@Z00H@Z
int Fxxx_i(x fnptr, x fnptr2, x fnptr3) ?Fxxx_i@@YAHP6AHH@Z00@Z
int Fxyxy_i(x fnptr, y fnptr2, x fnptr3, y fnptr4) ?Fxyxy_i@@YAHP6AHH@ZP6AHF@Z01@Z
void myclass::operator delete(void *p) ??3myclass@@SAXPAX@Z
int myclass::Fi_i(int bar) ?Fi_i@myclass@@QAEHH@Z
static int myclass::Fis_i(int bar) ?Fis_i@myclass@@SAHH@Z
void __cdecl myclass::Fv_v_cdecl(void) ?Fv_v_cdecl@myclass@@QAAXXZ
void __fastcall myclass::Fv_v_fastcall(void) ?Fv_v_fastcall@myclass@@QAIXXZ
void __stdcall myclass::Fv_v_stdcall(void) ?Fv_v_stdcall@myclass@@QAGXXZ
myclass::myclass(int x) ??0myclass@@QAE@H@Z
myclass::myclass(void) ??0myclass@@QAE@XZ
int myclass::nested::Fi_i(int bar) ?Fi_i@nested@myclass@@QAEHH@Z
myclass::nested::nested(void) ??0nested@myclass@@QAE@XZ
myclass::nested::~nested() ??1nested@myclass@@QAE@XZ
myclass myclass::operator+(int x) ??Hmyclass@@QAE?AV0@H@Z
myclass myclass::operator++() ??Emyclass@@QAE?AV0@XZ
myclass myclass::operator++(int) ??Emyclass@@QAE?AV0@H@Z
myclass& myclass::operator=(const myclass& from) ??4myclass@@QAEAAV0@ABV0@@Z
myclass::~myclass() ??1myclass@@QAE@XZ
int nested::Fi_i(int bar) ?Fi_i@nested@@QAEHH@Z
nested::nested(void) ??0nested@@QAE@XZ
nested::~nested() ??1nested@@QAE@XZ
void* myclass::operator new(size_t size) ??2myclass@@SAPAXI@Z

Dan Kegel
Last update: 30 April 2002
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值