C++ 为什么我的链接器脚本中的ENTRY()未设置为&书信电报;地址>;部门?
我试图将我正在构建的静态链接二进制文件的入口点重新定位为一个固定值,这样它就可以通过引导加载程序加载到内存区域中,并通过函数指针解引用跳入内存。下面是我正在使用的加载程序脚本:C++ 为什么我的链接器脚本中的ENTRY()未设置为&书信电报;地址>;部门?,c++,c,linker,C++,C,Linker,我试图将我正在构建的静态链接二进制文件的入口点重新定位为一个固定值,这样它就可以通过引导加载程序加载到内存区域中,并通过函数指针解引用跳入内存。下面是我正在使用的加载程序脚本: ENTRY(main) SECTIONS { . = 0x0000000000200000; .text : { *(.text) . = ALIGN(8); } .data : {
ENTRY(main)
SECTIONS
{
. = 0x0000000000200000;
.text : {
*(.text)
. = ALIGN(8);
}
.data : {
*(.data)
*(.rodata)
. = ALIGN(8);
}
__bss_start = .;
.bss : {
bss = .; _bss = .; __bss = .;
*(.bss);
}
end = .; _end = .; __end = .;
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
}
以下是我用于最终链接的命令行:
...
CC = g++
CFLAGS = -g -mcmodel=large -fPIC -T src/controlix.ld -Wl,--no-relax -static -nostdlib -static-libgcc
...
$(CC) $(CFLAGS) $(shell find bin/ -name "*.o") -o $(TARGET_OBJ)
(为了简洁起见,省略了构建系统其余部分的详细信息,我认为其中任何部分都不相关)
所以,我假设当我查看结果controlix.o二进制文件时,我应该看到main()符号位于0x200000,对吗?错:
$ nm bin/controlix.o |grep main
000000000021d0c6 t _GLOBAL__sub_D_main.cpp
000000000021d087 t _GLOBAL__sub_I_main.cpp
000000000021cef1 T main
0000000000256e11 t _ZL8eiremainPtS_P7LDPARMS
我做错了什么
我应该看到main()符号位于0x200000,对吗
不,想象一下在调用main之前要做多少事情。在许多系统上,库必须初始化,构造函数和析构函数称为(C++)。bss归零和.data初始化+许多其他我现在不记得的事情
main
是C
程序的入口点,但不是(在几乎所有已知的实现中)可执行文件的入口点
如果希望首先调用您的函数,请将其放在单独的段中,并修改链接器脚本
.text : {
*(.beforetext)
. = ALIGN(8);
__text_start = .;
*(.text)
. = ALIGN(8);
}
extern unsigned __text_start;
void __attribute__((section(".beforetext"))) myEntryFunc(void)
{
....
((void (*)(void))(&__text_start))(); // call the original executable entry point
}