Name Mangling
by: G.E. Ozz Nixon Jr.
Published: May 2009
©opyright 2009 by Friends of FPC
When compiling your software to link with external libraries (any OS), you will
eventually run into the problem where the API names are not exactly when the binary contains. This is called
name mangling and was introduced for C++ (and other languages which support overloaded method names). This
brief research document reflects my recent findings.
cdecl produces a name with a leading "_" (underscore).
int _cdecl myroutine (int a) {
return 0;
}
produces the exported method name "_myroutine" (without the quotations of course).
Same for a pascal compiled routine.
function myroutine (a:Integer):Integer; cdecl;
Begin
Result:=0;
End;
produces the exported method name "_myroutine".
Further investigating shows stdcall produces a name with a leading "_" (underscore) and the return size.
int _stdcall myroutine (int a) {
return 0;
}
produces the exported method name "_myroutine@4". While fastcall produces a name with a leading "@" (at sign).
int _fastcall myroutine (int a) {
return 0;
}
produces the exported method name "@myroutine@4". That was the end of the "easy" ones, once I started these tests with C++ compilers,
I had to throw out all rules, as each vendor seems to do something a little different. For example, when exporting a semi-complex
object the names took on a new naming convention.
I say names like "_ZN@9namespace@9classname@6method@E", length followed by the 'layer'. The delimiter was different on many of the compilers,
but appears that it just need to be consistent in the exported method name. The following chart shows different compilers exporting the same
source as different mangling naming.
Compiler Used
void h(int)
void h(int, char)
void h(void)
Intel C++ 8.0 for Linux
_Zlhi
_Zlhic
_Zlhv
GCC 3.x and 4.x
_Zlhi
_Zlhic
_Zlhv
HP aC++ A.05.55 IA-64
_Zlhi
_Zlhic
_Zlhv
HP aC++ A.03.45 PA-RISC
h__Fi
h__Fic
h__Fv
GCC 2.9x
h__Fi
h__Fic
h__Fv
MS Visual C++ v6/7
?h@@YAXH@Z
?h@@YAXHD@Z
?h@@YAXXZ
Borland C++ v3.x
@h$qi
@h$qizc
@h$qv
FreePascal 2.x (objdump)
P$TEST_H$LONGINT
P$TEST_H$LONGINT$CHAR
P$TEST_H
FreePascal 2.x (nm)
h
h
h
FreePascal Name Mangling Rules:
DATA
All variable names are converted to upper case
Variables in the main program or private to a unit have an underscore (_) prepended to their names.
Typed constants in the main program have a TC__ prepended to their names
Public variables in a unit have their unit name prepended to them : U_UNITNAME_
Public and private typed constants in a unit have their unit name prepended to them :TC__UNITNAME$$
CODE
All routine names are converted to upper case
Routines in a unit have their unit name prepended to them : _UNITNAME$$_
All Routines in the main program have a _ prepended to them
All parameters in a routine are mangled using the type of the parameter (in uppercase) prepended by the $ character. This is done in left to right order for each parameter of the routine
Objects and classes use special mangling : The class type or object type is given in the mangled name; The mangled name is as follows: _$$_TYPEDECL_$$ optionally preceded by mangled name of the unit and finishing with the method name
To override the above rules, Free Pascal supports 2 addition keywords:
public:
For a method that has the "public" modifier, the mangled name will be the name
exactly as it is declared.
alias:
For a method that has the "alias" modifier, the alias name is exported
exactly as it is declared.
procedure myroutine(a:integer);
cdecl; export; [public, alias '_Zlhi'];
Begin
// code //
End;
As you can guess, this has been both educational and frustrating to us when developing binraries to float across different platforms. Free
Pascal Compiler does it's best in doing the correct name mangling for the target operating system, and allows you to have more control to enforce a specific naming
convention if you wish. However, that is as far as they can go, and with good reason. Other issues exist when mixing C++ libraries, exception handling, virtual table layout, structure padding, etc. cause problems across compilers, even across versions of the same compiler. One of the cons of C++ object development, there isn't a stand because their can't be one with so many different "cooks in the kitchen". If you have any questions, or more information you would like to contribute to this topic, please feel free to submit it!!
G.E. Ozz Nixon Jr.