이런 프로그램을 사용하세요
int main()
{
return 0;
}
- 그리고 정적으로 링크하면 시스템의 일부 라이브러리가 최종 바이너리에 링크됩니다.
- 그리고 동적 연결을 사용하면 런타임에 라이브러리가 로드됩니까?
본질적으로 가장 간단한 프로그램에도 항상 라이브러리가 필요합니다. 그렇다면 그 이유는 무엇입니까? 실행하려는 모든 것에 대한 표준 진입점이 실제로 _start라고 생각하기 때문에 이 질문을 합니다(내 생각에는 glibc라는 라이브러리에 있는 것 같습니다). 어쩌면 설정 측면에서 _start가 정확히 무엇을 하는지 이해하지 못할 수도 있으므로 거기에 있는 포인터도 도움이 될 것입니다.
답변1
표준 이식 가능한 C로 프로그램을 작성하려면 main()
먼저 함수를 호출하는 런타임을 호출하기 위한 런타임이 필요합니다.
그러나 이에 대해 신경 쓰지 않는다면 라이브러리를 생략하고 인라인 어셈블리를 통해 직접 시스템 호출을 수행할 수 있습니다. 예를 들어. x86-64의 경우:
$ cat q.c
#include <sys/syscall.h>
void _start(void){
__asm__( "syscall" : : "D"(0), "a"(SYS_exit) );
}
$ cc -O2 -static -nostdlib -nostartfiles -Wall q.c -o q
$ strace ./q
execve("./q", ["./q"], 0x7fffc72d8d20 /* 39 vars */) = 0
exit(0) = ?
+++ exited with 0 +++
최소한 하나의 시스템 호출을 해야 합니다. 즉, _exit(2)
"가장 간단한 프로그램"이 충돌 종료를 허용하지 않는 한, 이 경우 빈 파일도 괜찮습니다 ;-):
$ > foo.c
$ cc -static -nostdlib -nostartfiles -Wall foo.c -o ./foo
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ ./foo
Segmentation fault
내 생각에 당신이 하고 싶은 모든 것에 대한 정식 진입점은 실제로
_start
이는 사양이 없습니다. _start
링커가 사용할 기본 이름입니다. -e sym
옵션( -Wl,-e,sym
with gcc
)을 사용하여 다른 곳을 가리킬 수 있습니다.