gcc 에서 __builtin_xxxxxx 라는 확장함수들을 제공한다.

 

 

출처 : http://forum.falinux.com/zbxe/index.php?mid=lecture_tip&document_srl=550242

 

gcc 확장기능 이용하기 - __builtin_return_address

 

gcc의 확장기능에는 대표적인 세가지 기능이 있습니다.

builtin , attribute, lable 이렇게 세가지인데 한가지씩 살펴보도록 알아보도록 합니다.

 

void *__builtin_return_address(unsigned int LEVEL)

이 함수는 리턴수소, 즉 자신을 호출한 함수의 반환 위치 주소를 돌려 줍니다.

arm 으로 하면 현재 상태에서의 lr 을 반환해 주는 것입니다.

매개 변수 LEVEL 은 호출 지점을 몇번 거슬러 올라갈지를 지정합니다.

예제를 봅니다.

 

  1 #include <stdio.h>

  2 

  3 void depth_0(void)

  4 {

  5     void *where;

  6 

  7     where = __builtin_return_address(0);

  8 

  9     printf("%s where %p\n", __FUNCTION__, where);

 10 }

 11 

 12 void depth_1(void)

 13 {

 14     void *where;

 15 

 16     where = __builtin_return_address(1);

 17 

 18     printf("%s where %p\n", __FUNCTION__, where);

 19 }

 20 

 21 int main(void)

 22 {

 23     void *where;

 24 

 25     printf("main address %p\n", main);

 26 

 27     depth_0();

 28 

 29     return 0;

 30 }

 31 

 

실행 결과는 아래와 같습니다.

root@boggle70-desktop:tmp# gcc d0409.c ; ./a.out 

main address 0x804843b

depth_0 where 0x804845e

 

보시는 것처럼 main 의 주소는 0x804843b  이고 depth_0 를 호출한 지점은 0x804845e 입니다.

 

검증을 위해 objdump 로 살펴봅니다.

0804843b <main>:

 804843b: 55                    push   %ebp

 804843c: 89 e5                 mov    %esp,%ebp

 804843e: 83 e4 f0              and    $0xfffffff0,%esp

 8048441: 83 ec 20              sub    $0x20,%esp

 8048444: b8 3d 85 04 08        mov    $0x804853d,%eax

 8048449: c7 44 24 04 3b 84 04  movl   $0x804843b,0x4(%esp)

 8048450: 08 

 8048451: 89 04 24              mov    %eax,(%esp)

 8048454: e8 c3 fe ff ff        call   804831c <printf@plt>

 8048459: e8 86 ff ff ff        call   80483e4 <depth_0>

 804845e: b8 00 00 00 00        mov    $0x0,%eax

 8048463: c9                    leave  

 8048464: c3                    ret  

 

main 의 주소는 0804843b 이고

depth_0 의 호출 위치는 8048459

그곳에서 +4 되어 있는 복귀 주소는 804845e 입니다.

 

위의 소스를 arm 으로 컴파일 하면 에러가 납니다.

__builtin_return_address 를 1이상 줄수 없도록 gcc 가 cross compiler 를 생성했기 때문입니다.

 

특정 라이브러리가 문제를 일으키는데 어떤 함수에서 호출되었는지 모르는 경우 위의 코드를 사용하여

호출한 함수를 확인하여 break point 를 잡는다면 디버깅에 도움이 될수 있을 것 같습니다.

 

 

 

 

참조및 출처  : Binary Hacks - O'REILLY

'Linux > Linux 일반' 카테고리의 다른 글

file 을 file 로 mount 하기 (--bind)  (0) 2019.07.02
gcc의 확장기능 __builtin_xxxx function  (0) 2019.06.28
Raspberry Pi Buildroot  (0) 2019.06.12
dbus로 MPRIS 날려서 VLC 제어해보기  (0) 2019.02.25
Posted by Real_G

댓글을 달아 주세요