Table of Contents
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.
namespace Hello { struct World { template <typename T> T add(T x, T y) { return x + y; } }; }
We use it in the following way:
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) -> int is mangled into _ZN5Hello5World3addIiEET_S2_S2_. Meaning according to Itanium ABI convention:
_Z- All mangled names start with thisN- Namespace start5Hello- 5 character identifier (“Hello”)5World- 5 character identifier (“World”)3add- 3 character identifier (“add”)IiE- Template implemented asT = int(i means int)E- Namespace endT_- Return type is the same as template typeS2_- First argument as wellS2_- 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().
/* 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
/* 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; }
