요약
GDB에서 디맹글링이 필요한 경우 아래의 명령어 입력
set print asm-demangle on
Bash
복사
정의
맹글링
네임 맹글링(Name Mangling)이란
컴파일러 구조에서 네임 맹글링(name magling)은 프로그램에서 함수나 변수를 사용할 경우 선언시 사용했던 이름을 링커가 함수, 구조, 클래스, 다른 자료형의 이름에 추가 정보를 인코딩 하여 구별을 가능하게 한다. 이를 네임 데코리에션(Name Decoration)이라고도 부른다.
맹글링이 필요한 이유
객체 지향에서 오버로딩(Overloading)시 파라미터 형태에 따라 알아서 구별해 호출, 다른 Namespace 내에 있는 같은 이름의 함수와 변수에 대해 에러 없이 구별하여 호출 할 수 있는 것은 맹글링을 통해 고유한 이름들을 만들기 때문에 가능하다.
디버깅을 통한 맹글링 확인
네임 맹글링(Name Mangling)을 이해하기 위해서 C++에서 오버로딩(overloading)을 통해 예를 들어보겠습니다.
// g++ -o mangling mangling.cpp
#include <stdio.h>
int add(int a, int b){
return a+b;
}
int add(int a, int b, int c){
return a+b+c;
}
double add(double a, double b){
return a+b;
}
int main()
{
printf("1. %d\n", add(1,2));
printf("1. %d\n", add(3,4,5));
printf("1. %f\n", add(6.0, 7.0));
return 1;
}
C++
복사
위 예에 add라는 함수를 동일한 이름으로 만들었으며, 이를 파라미터에 따라 호출되는 함수가 달라집니다.
이렇게 용도 맞게 함수를 필요에 따라 호출하여 사용할 수 있게 만들면 컴파일러는 어떻게 add 함수를 호출했을때 프로그래머가 원하는 함수를 실행하는지 확인해 보겠습니다.
아래의 명령어를 통해 확인해보면(저는 peda가 설치되어 있어 demangle을 off했습니다.)
gdb -q ./mangling
set print asm-demangle off
pdisas main
Bash
복사
아래와 같이 call 부분이 _Z3add~~로 변경된 것을 확인할 수 있습니다.
아래의 명령어를 입력하여 add(int, int)를 확인해보겠습니다.
pdisas _Z3addii
Bash
복사
아래와 같이 int형 데이터(4Byte)를 레지스터로 부터 받아와 연산을 수행하는 것을 확인할 수 있습니다.
이를 아까 풀었던 디맹글링을 풀고 확인해보기 위해서 아래의 명령어를 입력하겠습니다.
set print asm-demangle on
pdisas main
Bash
복사
아래와 같이 같은 함수지만 전달받는 함수의 인자에 따라서 다르게 호출되는 함수명을 확인할 수 있습니다.
위에서 확인했던 것과 같이 맹글링에는 특정한 패턴이 존재하며, 위키피디아에서 설명하고 있는 맹글링 규칙은 아래와 같습니다.
Compiler | void h(int) | void h(int, char) | void h(void) |
Intel C++ 8.0 for Linux | _Z1hi | _Z1hic | _Z1hv |
HP aC++ A.05.55 IA-64 | _Z1hi | _Z1hic | _Z1hv |
IAR EWARM C++ | _Z1hi | _Z1hic | _Z1hv |
_Z1hi | _Z1hic | _Z1hv | |
_Z1hi | _Z1hic | _Z1hv | |
h__Fi | h__Fic | h__Fv | |
HP aC++ A.03.45 PA-RISC | h__Fi | h__Fic | h__Fv |
?h@@YAXH@Z | ?h@@YAXHD@Z | ?h@@YAXXZ | |
Digital Mars C++ | ?h@@YAXH@Z | ?h@@YAXHD@Z | ?h@@YAXXZ |
Borland C++ v3.1 | @h$qi | @h$qizc | @h$qv |
OpenVMS C++ v6.5 (ARM mode) | H__XI | H__XIC | H__XV |
OpenVMS C++ v6.5 (ANSI mode) | CXX$__7H__FIC26CDH77 | CXX$__7H__FV2CB06E8 | |
OpenVMS C++ X7.1 IA-64 | CXX$_Z1HI2DSQ26A | CXX$_Z1HIC2NP3LI4 | CXX$_Z1HV0BCA19V |
SunPro CC | __1cBh6Fi_v_ | __1cBh6Fic_v_ | __1cBh6F_v_ |
Tru64 C++ v6.5 (ARM mode) | h__Xi | h__Xic | h__Xv |
Tru64 C++ v6.5 (ANSI mode) | __7h__Fi | __7h__Fic | __7h__Fv |
Watcom C++ 10.6 | W?h$n(i)v | W?h$n(ia)v | W?h$n()v |
저희도 잘 맹글링된 것을 확인할 수 있습니다.