web-dev-qa-db-ja.com

すべてのCプログラムはライブラリをロードする必要がありますか?

のようなプログラムで

int main()
{
   return 0;
}
  • 静的にリンクすると、システム上のライブラリが最終的なバイナリにリンクされます。
  • 動的にリンクすると、実行時にライブラリが読み込まれますか?

本質的に、最も単純なプログラムでもライブラリは常に必要ですか?実行したいすべての正規のエントリポイントは実際には_start(ライブラリにあると思ったglibc)だと思ったので、質問します。多分私は_startが設定に関して本当に何をしているのか理解していないので、そこにあるポインタも参考になるでしょう。

4
Andrew Cina

標準のポータブル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 +++
_

空のファイルでも実行できる「最も単純なプログラム」でクラッシュによる終了が許容されない限り、少なくとも1つのシステムコール、つまり_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)を使用して他の場所を指すことができます。

10
mosvy