34

gccでコンパイルされたCプログラムのエントリポイントを変更するにはどうすればよいですか?
次のコードのように

#include<stdio.h>
int entry()  //entry is the entry point instead of main
 {
   return 0;
 }
4

4 に答える 4

43

これはリンカー設定です:

-Wl,-eentry

物事はリンカに引数を渡し、-Wl,...リンカは-eエントリ関数を設定するために引数を取ります

于 2011-09-21T03:31:13.817 に答える
9

ソースコードは次のように変更できます。

#include<stdio.h>

const char my_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";

int entry()  //entry is the entry point instead of main
{
   exit(0);
}

「.interp」セクションを使用すると、プログラムで外部共有ライブラリを呼び出すことができます。exit呼び出しは、returnではなくexitプログラムへのエントリ関数を作成します。

次に、実行可能な共有ライブラリとしてプログラムをビルドします。

$ gcc -shared -fPIC -e entry test_main.c -o test_main.so
$ ./test_main
于 2014-08-10T04:18:21.870 に答える
8

GNU Binutils(Linuxなど)を提供するシステムを使用している場合は、このobjcopyコマンドを使用して、任意の関数を新しいエントリポイントにすることができます。

関数program.cを含むと呼ばれるファイルを想定します。entry

$ cat > program.c
#include <stdio.h>
int entry()
{
    return 0;
}
^D
  1. まず、を使用してコンパイルし-c、再配置可能なオブジェクトファイルを生成します。

    $ gcc -c program.c -o program.o
    
  2. 次に、次のように再定義entryしますmain

    $ objcopy --redefine-sym entry=main program.o
    
  3. 次に、gccを使用して新しいオブジェクトファイルをコンパイルします。

    $ gcc program.o -o program
    

注:プログラムにすでに「」という関数がある場合は、手順2の前に、別の呼び出しmainを実行できます。objcopy

objcopy --redefine-sym oldmain=main program.o
于 2015-12-14T22:26:07.900 に答える
2

最小限の実行可能な例と他の回答に関する注記

main.c

#include <stdio.h>
#include <stdlib.h>

int mymain(void) {
    puts("hello");
    exit(0);
}

コンパイルして実行します。

gcc -nostartfiles -Wl,--entry=mymain -o main.out main.c
# or -Wl,-emymain
./main.out 1 2 3

注釈:

  • がない-nostartfilesと、リンクは次のように失敗します。

    /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: error: ld returned 1 exit status
    

    おそらく、mainの前に実行されるglibcセットアップコードが_start通常はを呼び出すためmainです。

  • コマンドライン引数は設定されていません。おそらく、mainの前に実行されるglibcコードによって設定されるため、これらを使用しようとすると、未定義の値が出力されます。私は彼らのために働く方法を見つけていません。

Ubuntu20.10でテスト済み。

于 2019-10-29T18:56:30.487 に答える