(g)libc を使用せずに C コードをコンパイルしたいと考えています。どうすれば非アクティブ化でき、どの機能がそれに依存していますか?
-nostdlib を試しましたが、役に立ちません。コードはコンパイル可能で実行可能ですが、実行可能ファイルの 16 進ダンプで libc の名前を見つけることができます。
コードを でコンパイルすると-nostdlib、(もちろん) C ライブラリ関数を呼び出すことはできませんが、通常の C ブートストラップ コードも得られません。特に、Linux 上のプログラムの実際のエントリ ポイントはmain()ではなく、 と呼ばれる関数_start()です。標準ライブラリは通常、何らかの初期化コードを実行してから を呼び出すバージョンを提供しますmain()。
これをコンパイルしてみてくださいgcc -nostdlib -m32:
void _start() {
/* main body of program: call main(), etc */
/* exit system call */
asm("movl $1,%eax;"
"xorl %ebx,%ebx;"
"int $0x80"
);
}
この_start()関数は、常に への呼び出しexit(または などの戻り値のないシステム コールexec) で終了する必要があります。上記の例では、通常exit()は使用できないため、インライン アセンブリを使用してシステム コールを直接呼び出します。
最も簡単な方法は、C コードをオブジェクト ファイルにコンパイルし (gcc -cいくつかのファイルを取得するため*.o)、それらをリンカーで直接リンクすることです ( ld)。オブジェクト ファイルをいくつかの追加のオブジェクト ファイルとリンクする必要があります。たとえば/usr/lib/crt1.o、動作する実行可能ファイルを取得するためです (カーネルから見たエントリ ポイントとmain()関数の間には、少し作業が必要です)。何とリンクするかを知るには、 を使用して glibc とリンクしてみてくださいgcc -v。
gcc が生成するコードは、いくつかの隠し関数に依存している可能性があります。それらのほとんどはにありますlibgcc.a。また、libc に含まれるmemcpy()、memmove()、memset()およびへの隠し呼び出しが存在する可能性memcmp()があるため、独自のバージョンを提供する必要がある場合があります (少なくとも、パフォーマンスにこだわりすぎない限り、これは難しくありません)。
生成されたアセンブリ (フラグを使用)を見ると、状況がより明確になる場合があります。-S