Site Tools


name-mangling

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 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().

/*
 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;
}

Itanium ABI

name-mangling.txt · Last modified: (external edit)