자료 저장소

출처 : http://blog.naver.com/hermet?Redirect=Log&logNo=103985593

오늘 정리해볼 내용은 C/C++에서의 네임 맹글링 입니다.

 

뭐 실제 프로그래밍에 있어서 거의 도움될 내용은 아니지만,

평소에 궁금하셨던 분 또는 심심하신 분들은 그냥 재미삼아 한번 읽어보세요. ㅋ

 

본 게시물을 읽기 전에 이전 게시물 extern "C" (http://hermet.pe.kr/tb/87864741) 과 콜링 컨벤션 (http://hermet.pe.kr/51152911)을  먼저 참고하시면 도움이 될 것입니다.

 

 

 

그럼 시작하겠습니다. (Here we go~)  ..... (to Hell... 응?)

 

 

정확하게 네임 맹글링 ( Name Mangling ) 또는 네임 데코레이션 ( Name Decoration ) 이라고 하는데,

 

컴파일러는 각 코드 파일을 컴파일하면서 함수 이름들을 변경하게 됩니다. 이는 각 파일마다 존재할 수 있는 동일한 함수명들을 링커(Linker)가 구분하기 위해서이죠.

 

컴파일러는 함수에 대해서 함수의 이름, 파라미터, 콜링 컨벤션(Calling Convention), 네임 스페이스(Namespace) 등을 사용하여 심볼 이름을 만들어 내는데,  사실 이는 컴파일러마다 규칙이 다를 수 있으며 기본적으로 대략 다음 순서로 만들어집니다. (아래 기준은 ms 사의 컴파일러)

 

 

1. prefix '?'

2. 클래스 이름을 제외한 "함수 이름". 

      2.1 만약 함수가 연산자, 생성자, 소멸자일 경우 다음과 같은 2문자로 대처됨

            2.1.1   생성자 - "?0"

            2.1.2   소멸자 - "?1"

            2.1.3   operator new - "?2"

            2.1.4   operator =  - "?3"

            2.1.5   operator + - "?H"

            2.1.6   operator++ - "?E"

           2.1.7  그 외의 것들은 생략... 직접 컴파일해서 확인해 보세요... -_-a

      2.2 그렇지 않으면 함수 이름 끝에 '@'

4. 함수가

     4.1 클래스 멤버함수 였다면,

            4.1.1  해당 멤버 함수의 "클래스 이름Q" ( 만약 inner 클래스에 포함되어 있다면, inner -> outer 순으로. )

            4.1.2  '@'

            4.1.3  'Q'

     4.2 일반 함수면,

            4.2.1 '@'

            4.2.2 'Y'

5. 콜링 컨벤션에 따른 시그니처

      5.1 __cdecl - 'A'

      5.2 __fastcall - 'I'

      5.3 __stdcall - 'G'

      5.4 __thiscall -'E'

      5.5 __fortran - 'C'

      5.6 __pascal - 'C'

6. 함수의 반환 타입에 따른 시그니처  (아래 MS C++ Type codes 참고 )

7. 함수 파라미터에 따른 시그니처 (아래 참고)  (argument 리스트의 마지막에 '@')

8. 'Z'

 

void - 'X'

bool - '_N'

char - 'D'

signed char - 'C'

unsigned char - 'E'

short - 'F'

unsigned short -'G'

int - 'H'

unsigned int - 'I'

long - 'J'

unsigned long - 'K'

__int64 - '_J'

unsigned __int65 - '_K'

wchar_t - 'G'

float - 'M'

double - 'N'

long double - 'O'

struct/class - 'V'

array - 'Q'

pointer - 'P'

funtion pointer - "P6"

<MS C++ Type codes >

 

deault - 'A'

near - 'A'

const - 'B'

volatile - 'C'

const volatile -'D'

far - 'E'

const far - 'E'

volatile far - 'G'

const volatile far - 'H'

huge - 'I'                  // 응? 뭐지 -_-?

<MS C++ Storge class codes >

 

near - 'Y' / 'Q'

far - 'Z' / 'R'

<MS C++ Function calling distance codes >

 

default - '?A'

const - '?B'

volatile - '?C'

const volatile - '?D'

<MS C++ Storage class codes for return >

 

default - 'Q'

static - 'S'

virtual - 'U'

<MS C++ Member function modifier codes >

 

default - 'A'

const - 'B'

volatile - 'C'

const volatile -'C'

<MS C++ Member function modifier codes >

 

 

그럼 실제 예를 통해 한번 확인해 보도록 합시다. 한번 위에서 설명한 네임 맹글링 룰과 매칭해서 비교해 보세요.

 

void Print();                              ->   ?Print@@YAXXZ

Test ::Print();                            ->  ?Print@Test@@QAEXXZ

Test ::Test2 ::Print();                  ->  ?Print@Test2@Test@@QAEXXZ

void Print( int , char* );               ->  ?Print@@YAXHPAD@Z

 

 

 

마지막으로, 심볼 이름으로부터 실제 함수 명을 확인할 수 있는 툴을 설명하자면, 비주얼 스튜디오에 undname 이라는 프로그램이 있습니다.

 

 

심볼 이름을 먼저 확인한 후,

 

 

undname 프로그램으로 확인해 봅니다.

 

 

그리고 리눅스에서도 물론 c++filt 또는 nm 이라는 프로그램이 있지요.

 

지금 리눅스가 작동안하는 관계로... 사용방법만 적어보도록 하겠습니다. (그런 쌩뚱맞을 수가! -_- )

 

nm Print.o | c++filt

nm --demangle Print.o

 

 

 

(참고 - http://www.kegel.com/mangle.html#operator

        - Windows 구조와 원리, 한빛 미디어, 정덕영 저, 115 - 118)

 

댓글 로드 중…

최근에 게시된 글