모든 C 프로그램은 라이브러리를 로드해야 합니까?

모든 C 프로그램은 라이브러리를 로드해야 합니까?

이런 프로그램을 사용하세요

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,symwith gcc)을 사용하여 다른 곳을 가리킬 수 있습니다.

관련 정보