링커는 x86-64 ELF 형식 실행 파일에서 main 함수를 어떻게 찾습니까?링커가 주 기능을 어떻게 찾습니까?
답변
매우 일반적인 개요 인 링커는 기호 main
으로 식별되는 코드 블록에 주소를 할당합니다. 오브젝트 파일에있는 모든 심볼에 적용됩니다.
사실 실제 주소를 지정하지는 않지만 프로그램 실행시 로더가 실제 주소로 변환 할 일부 기본 주소를 할당합니다.
실제 진입 점은 main
이 아니지만 main을 호출하는 crt의 일부 기호입니다. LD는 something different을 지정하지 않는 한 기본적으로 기호 start
을 찾습니다.
링크 된 코드는 실행 파일의 .text
부분에서 끝이 같은 (매우 간단) 볼 수 있었다 :
Address | Code
1000 someFunction
...
2000 start
2001 call 3000
...
3000 main
...
링커가 주소 2000의 엔트리 포인트를 지정합니다 ELF 헤더를 기록
objdump
과 같은 실행 파일의 내용을 덤프하여 main
의 상대 주소를 가져올 수 있습니다. 런타임시 실제 주소를 얻으려면 기호 funcptr ptr = main;
을 읽고 main
의 서명이있는 함수에 대한 포인터로 funcptr
이 정의됩니다. 링커 제 상대 주소 심볼 main
를 해결할 보낸 심벌 제거되었는지
typedef int (*funcptr)(int argc, char* argv[]);
int main(int argc, char* argv[])
{
funcptr ptr = main;
printf("%p\n", ptr);
return 0;
}
메인의 어드레스에 관계없이 정확하게 해결한다.
은 다음과 같이 objdump를 사용 : 나는 윈도우 그렇게 결과가 약간 다를 수 Cygwin에서 사용 오전
$ objdump -D funcptr.exe | grep main
40102c: e8 af 01 00 00 call 4011e0 <_cygwin_premain0>
401048: e8 a3 01 00 00 call 4011f0 <_cygwin_premain1>
401064: e8 97 01 00 00 call 401200 <_cygwin_premain2>
401080: e8 8b 01 00 00 call 401210 <_cygwin_premain3>
00401170 <_main>:
401179: e8 a2 00 00 00 call 401220 <___main>
004011e0 <_cygwin_premain0>:
004011f0 <_cygwin_premain1>:
00401200 <_cygwin_premain2>:
00401210 <_cygwin_premain3>:
00401220 <___main>:
참고 :
$ objdump -f funcptr.exe
funcptr.exe: file format pei-i386
architecture: i386, flags 0x0000013a:
EXEC_P, HAS_DEBUG, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x00401000
특별히
main
을 찾고, 내 컴퓨터에서 나는이 얻을. 나를 위해
00401170
에 사는
main
모양입니다.
따라서 런타임 전에 '메인'의 주소가 무엇인지 판단 할 방법이 없습니까? – RouteMapper
지금 내가 수정 한 소식을 보았습니다. 나는'start'의 주소가 ELF 헤더에 있다는 것을 알고 있습니다. 하지만'main'의 주소를 정적으로 계산할 방법이 있습니까? main의 주소가 동적으로 재배치되는 경우가 있습니다. – RouteMapper
@RouteMapper 정적 분석을하고 있습니다. 맞습니까? 재배치가 존재하지 않습니다. 재배치하는 것은 로더의 직업이며, 당신은 로더 *입니다. 단지 재배치하지 않기로 결정했습니다. – harold
는 Binutils의에, 하나에 의해 결정됩니다
이-e
CLI 옵션 이
- 당신은 당신의 링커 스크립트를 볼 수 있습니다
링커 스크립트 :
ld --verbose
가 내 포함 :
ENTRY(_start)
은 다음 링크시의 _start
기호를 포함 crt1.o
같은 glibc에 제공하는 오브젝트 파일은 main.o
와 함께 링커에 전달됩니다.
이러한 개체 파일은 argv
과 같은 설정을 한 다음 main
기능을 호출합니다.
gcc -v
으로 몰래 들어간 여분의 오브젝트 파일을 볼 수 있습니다. 엔트리 포인트를 호출하는 프로그램 실행 https://sourceware.org/binutils/docs/ld/Entry-Point.html#Entry-Point
제 조작법 :
은이 설명된다. ENTRY 링커 스크립트 명령을 사용하여 진입 점을 설정할 수 있습니다.
ENTRY(symbol)
가 엔트리 포인트를 설정하는 방법은 여러 가지가 있습니다 인수는 심볼 이름입니다. 그 중 하나가 성공하면 링커는 순서대로 다음 각각의 방법을 시도하고 중지하여 진입 점을 설정합니다 :
- 은`-e '항목 명령 줄 옵션을;
- 링커 스크립트의 ENTRY (symbol) 명령.
- 타겟 특정 기호의 값 (정의 된 경우). 많은 타겟에서 이것은 시작이지만 PE와 BeOS 기반 시스템은 발견 된 첫 번째 심볼과 일치하는 가능한 엔트리 심볼 목록을 확인합니다.
- `.text '섹션의 첫 번째 바이트 주소 (있는 경우).
- 주소도 0
참조 : // 유래 : is there a GCC compiler/linker option to change the name of main?
- 1. .exe의 진입 점 기능을 어떻게 찾습니까?
- 2. 전화 번호는 어떻게 찾습니까?
- 3. 구조체의 크기는 어떻게 찾습니까?
- 4. 적절한 UUID는 어떻게 찾습니까?
- 5. 발신자 기능은 어떻게 찾습니까?
- 6. FileInputStream은 어떻게 파일을 찾습니까?
- 7. - 프로세스 ID는 어떻게 찾습니까?
- 8. SVN 소스는 어떻게 찾습니까?
- 9. 요일을 어떻게 찾습니까?
- 10. Cmake는 어떻게 파일을 찾습니까?
- 11. CoreLocation은 어떻게 장치를 찾습니까?
- 12. JUnit은 테스트를 어떻게 찾습니까?
- 13. 셀 내용에서 행을 어떻게 찾습니까?
- 14. 링커가 실행 파일에서 주 루틴을 제거하지 않는 이유는 무엇입니까?
- 15. ContentResolver는 어떻게 해당 ContentProvider를 찾습니까?
- 16. 디버깅에서 호출하는 방법을 어떻게 찾습니까?
- 17. javac.exe는 프로그래밍 방식으로 어떻게 찾습니까?
- 18. Solaris에서 gcc가 어떻게 라이브러리를 찾습니까?
- 19. TestNG는 테스트 클래스를 어떻게 찾습니까?
- 20. grok - 인용 문자열을 어떻게 찾습니까?
- 21. seekg는 파일의 끝을 어떻게 찾습니까?
- 22. 돼지에서 2 위를 어떻게 찾습니까?
- 23. TCP 소켓의 inode는 어떻게 찾습니까?
- 24. 메쉬 객체의 높이를 어떻게 찾습니까?
- 25. Android에서 기본 글꼴은 어떻게 찾습니까?
- 26. Tomcat은 webapps 디렉토리를 어떻게 찾습니까?
- 27. RichTextBox에서 반복되는 텍스트는 어떻게 찾습니까?
- 28. jQuery를 사용하여 #을 어떻게 찾습니까?
- 29. Go는 가져온 패키지를 어떻게 찾습니까?
- 30. make는 모듈의 순서를 어떻게 찾습니까?
는 HTTP ([(.so를가) 링커에 의해 처리되는 방법 공유 객체 내부) (주요 기능] 참조 .com/questions/9807194/how-main-function-inside-a-shared-object-so-taken-take-by-linker) –
[어떻게 C++ 링크가 실제로 작동합니까?] http://stackoverflow.com/a/12122534/309483)? 어느 부분을 이해하지 못합니까? –
main 함수의 메모리 주소를 어떻게 결정할 수 있는지 이해할 수 없습니다. – RouteMapper