Skip to content
Advertisement

What counts as a symbol while mangling C++ names on Linux?

On Linux g++/clang++

void test10058l(void*(*)(void*),void*(*)(const void*),const void*(*)(void*));

is mangled as _Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E

  • According to g++/clang++, how many symbols are there in this function definition ?
  • What are the substitutions ? (S_, S0_, S1_, …)
  • More specifically what is S3_ ?

(edit – adding some context)

The D language allows to interact with C++ by declaring symbols as extern(C++).

Unfortunately the current implementation is not always correct – I’m trying to fix it by implementing the current g++/clang++ name mangling scheme as defined by the Itanium C++ ABI.

Since this documentation is not crystal clear, I’m having a hard time understanding what accounts as a symbol.

Advertisement

Answer

After several experiments I managed to understand how symbols are substituted. In particular, qualified types create new symbols and function account for symbols by themselves. A pointer to a function is then another symbol.

Here is the breakdown of the substitutions for the example I provided.

void test10058l(void*(*)(void*),void*(*)(const void*),const void*(*)(void*));

    _Z10test10058lPFPvS_EPFS_PKvEPFS3_S_E
S_                  ^^                    : Pv          void*
S0_                ^^^^^^                 : FPvS_E      void*()(void*)
S1_               ^^^^^^^                 : PFPvS_E     void*(*)(void*)
S2_                           ^^          : Kv          const void
S3_                          ^^^          : PKv         const void*
S4_                       ^^^^^^^         : FS_PKvE     void*()(const void*)
S5_                      ^^^^^^^^         : PFS_PKvE    void*(*)(const void*)
S6_                               ^^^^^^^ : FS3_S_E     const void*()(void*)
S7_                              ^^^^^^^^ : PFS3_S_E    const void*(*)(void*)

I started this git repository to report my findings regarding linux/osx GCC C++ name mangling.

Advertisement