2010-04-15 6 views
1

누군가 다음 코드가 어떻게 작동하는지 설명 할 수 있습니까? 메모리 섹션 정보 얻기

# if defined(__ELF__) 
# define __SECTION_FLAGS ", \"aw\" , @progbits" 
    /* writable flag needed for ld ".[cd]tors" sections bug workaround) */ 
# elif defined(__COFF__) 
# define __SECTION_FLAGS ", \"dr\"" 
    /* untested, may be writable flag needed */ 
# endif 

asm 
(
    ".section .ctors" __SECTION_FLAGS "\n" 
    ".globl __ctors_begin__\n" 
    "__ctors_begin__:\n" 
    ".previous\n" 
); 
asm /* ld ".[cd]tors" sections bug workaround */ 
(
    ".section .ctors0" __SECTION_FLAGS "\n" 
    ".globl __ctors0_begin__\n" 
    "__ctors0_begin__:\n" 
    ".previous\n" 
); 

마찬가지로 우리는 __ctors_end__, __ctors0_end__와 소멸자 위치가이 방법을 얻을 수있다 얻고있다. 일부 ld 버그 해결 방법 후에 __ctors_begin__에서 __ctors_end__까지의 포인터가 가리키는 모든 함수가 실행됩니다. 나는 어셈블러를 모른다. 그리고이 코드는 내가 해석하는 것이 불가능하다.

BTW : C에서 C++ 생성자/소멸자를 호출하는 것이 안전하거나 쉽지 않은 것으로 알고 있습니다.

+0

이 코드는 섹션을 생성하는 것이지 가져 오지 않습니다. 그거 어디서 났어? –

+0

섹션 작성 인 경우 생성자 생성 방법이이 새 섹션에 배치됩니까? 처음에 이것은 컴파일러가 넣은 일반적인 이름의 섹션에서 생성자를 추출한 것으로 생각했습니다. 이것은 C++로 작성된 Linux 커널 드라이버의 일부입니다. – Basilevs

답변

5

이것은 실제로 CPU에서 코드를 실행하는 것이 아니라 오브젝트 파일의 메타 데이터에 추가됩니다. 링커에게 생성자가 저장되는 최종 실행 파일의 동일한 섹션 (= 부분)에 일부 글로벌 변수 (위의 예에서는 __ctors_begin__)를 생성하도록 지시합니다 (해당 섹션은 .ctors입니다). 이 기능을 사용하려면 "begin"변수가있는 파일이 먼저 링크되고 "end"변수가있는 파일이 마지막에 연결되어 있는지 확인해야합니다 (단, __SECTION_FLAGS으로 제어 할 수도 있습니다). 그것은 당신에게 당신이 찾고있는 메모리 범위를 제공합니다.

"안전"과 관련 : 음, C++ 런타임은 마술이 아닙니다. 어떻게 든 시작시 모든 생성자 및 소멸자를 실행하는 방법을 알고 있어야하며 항상 변경되지는 않습니다. 따라서 컴파일러의 주요 버전 번호는 매우 안전해야합니다. 또한 깨지면 곧 알게 될 것입니다 :-)