如何使用gcc更改C程序的入口点?
如何更改使用gcc编译的C程序的入口点?如何使用gcc更改C程序的入口点?,c,main,entry-point,C,Main,Entry Point,如何更改使用gcc编译的C程序的入口点? 就像下面的代码一样 #include<stdio.h> int entry() //entry is the entry point instead of main { return 0; } #包括 int entry()//entry是入口点,而不是main { 返回0; } 这是一个链接器设置: -Wl,-eentry -Wl,东西将参数传递给链接器,链接器使用-e参数设置输入函数您可以将源代码修改为: #include
就像下面的代码一样
#include<stdio.h>
int entry() //entry is the entry point instead of main
{
return 0;
}
#包括
int entry()//entry是入口点,而不是main
{
返回0;
}
这是一个链接器设置:
-Wl,-eentry
-Wl,
东西将参数传递给链接器,链接器使用-e
参数设置输入函数您可以将源代码修改为:
#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);
}
如果您使用的系统提供(如Linux), 您可以使用
objcopy
命令
使任意函数成为新的入口点
假设一个名为program.c
的文件包含entry
函数:
$ cat > program.c
#include <stdio.h>
int entry()
{
return 0;
}
^D
条目重新定义为main
:
$ objcopy --redefine-sym entry=main program.o
$ gcc -c program.c -o program.o
$ gcc program.o -o program
main
的函数,在步骤2之前,您可以执行单独的objcopy
调用:
objcopy --redefine-sym oldmain=main program.o
最小可运行示例和其他答案的注释 main.c
#include <stdio.h>
#include <stdlib.h>
int mymain(void) {
puts("hello");
exit(0);
}
附注:
- 如果没有
,链接将失败:-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
中的glibc设置代码通常调用\u start
main
- 命令行参数不是为您设置的,可能是因为它们是由在main之前运行的glibc代码设置的,所以尝试使用它们会打印未定义的值。我还没有找到适合他们的方法
在Ubuntu20.10中测试。这是我用这个选项编译hello world C程序时得到的:
$gcc-Wl,-emymain t27.C/usr/lib/gcc/i686 redhat linux/4.8.2/../../../crt1.o:在函数“\u start”:(.text+0x18):对“main”的未定义引用。
@LeeDuhem,这是因为您将程序与标准c运行时库链接。与c运行时库链接的程序中的入口点是_start。Start引用了程序的main()(它希望程序使用main()func而不是自定义func)。尽量不要链接到crt并指定一个入口点作为您的\u main,看看会发生什么。@LeeDuhem,-nostlibs该标志是什么。-nostartfiles
是您想要的实际标志,它省略了包含\u start的crt*.o文件,但仍然允许您使用libc(除非您也使用-nostlib或-nodefaultlibs,在这种情况下,您仍然可以使用-lc-lgcc等手动指定它们。)我相信有一个输入错误:应该是-Wl,--entry=“MyCutomEntryFunction”
或-Wl,-e=“MyCutomEntryFunction”
什么是entry
函数的调用约定?C-runtime是否以这种方式初始化?请您解释一下“将程序构建为可执行的共享库”是什么意思怎么可能两者都是?@harper:这不是一个与C兼容的调用约定。ELF入口点ABI的主参数在堆栈指针中,指向一个“数组”由argc、argv指针、null、env指针、null、辅助向量表组成。某些ARCH在特定寄存器中有其他arg。不起作用..I get:无法执行二进制文件:Exec格式error@iandotkelly不是OP,但我需要使用一个检查点库,它要求我将main()更改为其他内容;)@Nubcake您知道链接器的选项--wrap=xxx
?它将xxx
的所有引用替换为\uuuuwrap\uxxx
,将xxx
的所有定义替换为\uuuuureal\uxxx
。我成功地将其用于测试main()
。不起作用,显然警告很严重。@ScottFranco您的GCC版本/OS版本是什么?C:\projects\petit\u ami>GCC-v。。。gcc版本9.2.0(MinGW.org gcc Build-2)@ScottFranco警告是由小的打字错误引起的-eentry=
应该是--entry=
;我已经相应地编辑了答案。@Demi Lune接球不错!我想知道在我的测试中它是如何与打字错误一起工作的!
gcc -nostartfiles -Wl,--entry=mymain -o main.out main.c
# or -Wl,-emymain
./main.out 1 2 3
/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