我从http://newlib.sourcearchive.com/documentation/1.18.0/init_8c-source.html查看了__libc_init_array的源代码.
但我不太明白这个功能是做什么的.
我知道这些符号
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (void) __attribute__((weak));
extern void (*__preinit_array_end []) (void) __attribute__((weak));
extern void (*__init_array_start []) (void) __attribute__((weak));
extern void (*__init_array_end []) (void) __attribute__((weak));
extern void (*__fini_array_start []) (void) __attribute__((weak));
extern void (*__fini_array_end []) (void) __attribute__((weak));
Run Code Online (Sandbox Code Playgroud)
在链接描述文件中定义.
链接器脚本的一部分可能如下所示:
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN …Run Code Online (Sandbox Code Playgroud) 我正在使用STMicroelectronics的STM32F746NG微控制器.该器件基于ARM Cortex-M7架构.我花了很多时间来理解示例项目中的linkerscript.我想出了基础知识,但我仍然无法掌握它的大部分内容.请帮我理解这些部分.
linkerscript开头如下:
/* Entry Point */
ENTRY(Reset_Handler) /* The function named 'Reset_Handler' is defined */
/* in the 'startup.s' assembly file. */
/* Highest address of the user mode stack */
/* Remember: the stack points downwards */
_estack = 0x20050000; /* End of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* Required amount of heap */
_Min_Stack_Size = 0x400; /* Required amount of stack */ …Run Code Online (Sandbox Code Playgroud) 我在哪里可以找到gcc使用的实际链接器脚本和设置?
我试过的事情:
具体来说,让我们考虑一个小程序:empty.c
int main(void)
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
静态构建它,并查看结果:
$ gcc -static -o empty empty.c
$ readelf -W -l empty
Elf file type is EXEC (Executable file)
Entry point 0x400f4e
There are 6 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0bf581 0x0bf581 R E 0x200000
LOAD 0x0bfeb0 0x00000000006bfeb0 0x00000000006bfeb0 0x001d80 0x0042d8 RW 0x200000
NOTE 0x000190 0x0000000000400190 0x0000000000400190 0x000044 0x000044 R 0x4
TLS 0x0bfeb0 0x00000000006bfeb0 0x00000000006bfeb0 0x000020 …Run Code Online (Sandbox Code Playgroud) 希望有一个可执行文件通过修改自己的全局常量来保存其状态.只是为了拥有一个完全独立的可执行文件.
想到的一些解决方案/黑客:
让链接器提供此信息是很好的.
是否可以让链接器提供可执行文件中只读部分的偏移量?
谢谢
我想在RAM中创建一个部分,分配一个特定的大小并将其放在一个地址?是否可以在不传递链接描述文件"文件"或不修改现有链接描述文件的情况下执行所有这些操作?
.myspace :
{
. = 0x10000;
. = . + STACK_SIZE;
} > ram
Run Code Online (Sandbox Code Playgroud)
是否可以在GNU LD/GCC的命令行中使用链接描述文件完成所有操作?
我收到链接错误:
危险搬迁:l32r:使用后放置文字:
我还在尝试调试; 但是,我想更好地理解这个错误.我明白搬迁是什么; 但是,我不确定它是多么危险,并且正在寻找一些澄清.此外,可能会产生此类错误的小代码段会很有帮助.
简而言之,什么是" 危险的搬迁 "?
在GCC中,MEMORY命令描述目标中内存块的位置和大小.必须以这种方式使用该命令.
MEMORY
{
name [(attr)] : ORIGIN = origin, LENGTH = len
...
}
Run Code Online (Sandbox Code Playgroud)
现在,我有一个链接器使用的链接器文件(基于GCC的tricore微控制器链接器,tricore-ld)以这种方式定义RAM内存部分:
MEMORY
{
ram (w!xp): org = 0x70000000, len = 32k
...
}
Run Code Online (Sandbox Code Playgroud)
你能解释(p!x p)中'p'的含义吗?'p'一般意味着什么?
有没有办法ld在Mac OS X上使用链接描述文件?
ldLinux上的GNU 程序接受一个-T <scriptname>选项,但在Mac OS -T上是一个未知的命令选项.如果可以解决问题的话,使用GCC的替代安装是可以的.
当我将我的osdev移动到Linux时,我遇到了一个问题,它之前在gcc 3.5.*和binutils 2.18(编译为输出x86_64-elf)上运行在cygwin下运行.
以下是信息:
gcc -v
Using built-in specs.
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.4-14ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5)
Run Code Online (Sandbox Code Playgroud)
ld -v
GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908
ld -help的一部分
....
ld: supported targets: elf32-i386 a.out-i386-linux pei-i386 elf32-little elf32-big elf64-x86-64 pei-x86-64 elf64-l1om elf64-little elf64-big plugin srec symbolsrec …Run Code Online (Sandbox Code Playgroud) 我有一些非空构造函数的全局实例的简单声明.这些构造函数在启动期间自动调用.我在Linux上交叉编译C++到不同的微控制器目标.
至于
对构造函数的调用将放入该.init_array部分.地图文件如下所示:
.init_array 0x00007cb8 0x4 libmotor.o
.init_array 0x00007cbc 0x4 libaudio.o
至于
这些调用进入该.ctors部分:
.ctors 0x000000009d011508 0x4 libmotor.o
.ctors 0x000000009d01150c 0x4 libaudio.o
编译完成后-ffunction-sections -fdata-sections,链接器得到了--gc-sections.
所有二进制文件都可以工作,但我想将所有调用放在同一部分(以简化链接器脚本的维护).