# Name mangling **Name mangling** is how C++ compilers encode object types then and reconstruct the type back. Let's say we got a following piece of C++ code. ```cpp namespace Hello { struct World { template T add(T x, T y) { return x + y; } }; } ``` We use it in the following way: ```cpp int main() { Hello::World world; return world.add(2, 3) } ``` The question is how does this translate to assembly language? The assembly language knows nothing about C++ syntax (namespaces, structs, templates. ...). The answer is a type like `Hello::World::add(int, int) -> int` is mangled into `_ZN5Hello5World3addIiEET_S2_S2_`. Meaning according to Itanium ABI convention: - `_Z` - All mangled names start with this - `N` - Namespace start - `5Hello` - 5 character identifier ("Hello") - `5World` - 5 character identifier ("World") - `3add` - 3 character identifier ("add") - `IiE` - Template implemented as `T = int` (i means int) - `E` - Namespace end - `T_` - Return type is the same as template type - `S2_` - First argument as well - `S2_` - Second argument as well Assembly code: ``` .weak _ZN5Hello5World3addIiEET_S2_S2_ .type _ZN5Hello5World3addIiEET_S2_S2_, @function _ZN5Hello5World3addIiEET_S2_S2_: push rbp mov rbp, rsp mov QWORD PTR -8[rbp], rdi mov DWORD PTR -12[rbp], esi mov DWORD PTR -16[rbp], edx mov edx, DWORD PTR -12[rbp] mov eax, DWORD PTR -16[rbp] add eax, edx pop rbp ret ``` ## C In C programming language symbols have the same name as they do in the code. You can tell by running `gcc -masm=intel -S func.c -o func.s` on this following code and looking at assembly `main.s` The symbol created by the label `func:` has the same name as the function `func()`. ```c /* Compile: gcc -masm=intel -S func.c -o func.s View: grep -v '\.cfi_' func.s ----------------------------------------------- .file "func.c" .intel_syntax noprefix .text .globl func .type func, @function func: .LFB0: push rbp mov rbp, rsp mov DWORD PTR -4[rbp], edi mov DWORD PTR -8[rbp], esi mov edx, DWORD PTR -4[rbp] mov eax, DWORD PTR -8[rbp] add eax, edx pop rbp ret .LFE0: .size func, .-func .ident "GCC: (GNU) 15.2.1 20251112" .section .note.GNU-stack,"",@progbits */ int func(int x, int y) { return x + y; } ``` ## C++ In C++ programming language, symbol names are mangled. They're different in assembly from When you name the exact same code `func.cpp` and compile it with `g++` to assembly, using `g++ -masm=intel -S func.cpp -o func.s`, then The symbol created by the label `_Z4funcii` ```cpp /* Compile: g++ -masm=intel -S func.cpp -o func.s View: grep -v '\.cfi_' func.s -------------------------------------------------- .file "func.cpp" .intel_syntax noprefix .text .globl _Z4funcii .type _Z4funcii, @function _Z4funcii: .LFB0: push rbp mov rbp, rsp mov DWORD PTR -4[rbp], edi mov DWORD PTR -8[rbp], esi mov edx, DWORD PTR -4[rbp] mov eax, DWORD PTR -8[rbp] add eax, edx pop rbp ret .LFE0: .size _Z4funcii, .-_Z4funcii .ident "GCC: (GNU) 15.2.1 20251112" .section .note.GNU-stack,"",@progbits: */ int func(int x, int y) { return x + y; } ``` ## Itanium ABI - https://itanium-cxx-abi.github.io/cxx-abi/abi.html ## Links - https://en.wikipedia.org/wiki/Name_mangling