问题标签 [linker-scripts]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
grammar - 在哪里可以找到正式的 ld 链接器脚本语法?
我正在寻找链接描述文件的正式语法。类似于给予 lex 和 yacc 但与其他 yacc 包袱不同的东西。如果我直接查看ld
. 但我现在不想这样做。
我看过这个问题及其答案,但它指的是ld
. 联机帮助页在很大程度上很好,但它们确实以某种模棱两可的方式指定了一些东西。例如,从作业中获取这个片段:定义符号它说:
例如,要创建一个绝对符号,其地址是名为 .data 的输出节的最后一个字节:
怎么解释...
?
这是一个例子。经过一番挣扎,我也许能够足够准确地解释这一件事;但是这样的例子很多;所以我的问题是:链接器脚本是否有更好的正式规范?The C Language
类似于您在Ritchie 和 Kernighan的书的附录中看到的 C 语法?
gcc - c - 将 .data 发送到不同的部分
我想获取.data
为特定 C 文件生成的部分中的符号,并将它们放在.mydata
最终可执行文件的不同部分(例如)中。例如,
默认情况下,两者都my_str
出现my_special_str
在该.data
部分中。但是,当我生成 时specialdata.o
,我想将任何可能出现的内容发送.data
到.mydata
.
我知道我可以使用__attribute__((section(".mydata")))
来实现此效果,但我不知道如何将其应用于结构的指针成员的指定初始值设定项(我已经简化了此问题的代码)。所以相反,我在想也许我可以使用链接器脚本并将特定文件中的所有数据发送到我的特殊部分。
我试过这个链接器脚本(link.lds
):
,gcc -c specialdata.c -T link.lds -o specialdata.o
但输出objdump -x specialdata.o
显示一个.data
部分但没有.mydata
部分。
我究竟做错了什么?
x86 - 这个 ASM 代码片段是什么意思?
我一直在尝试从这个( https://github.com/0xAX/linux-insides/blob/master/Booting/linux-bootstrap-1.md )教程中了解 Linux 启动过程,而且很早就开始了我遇到了以下代码片段。
我以前没有处理过很多 ASM,但我从未见过这样的事情。它有什么作用?花括号是什么意思?
c++ - 为什么 GCC 将对全局实例的构造函数的调用放入不同的部分(取决于目标)?
我有一些带有非空构造函数的全局实例的简单声明。这些构造函数在启动期间自动调用。我在 Linux 上将 C++ 交叉编译到不同的微控制器目标。
至于
- arm-none-eabi-gcc-4.8.4
- rx-elf-gcc-4.8-GNURX_v14.03 (GCC 4.8.3)
对构造函数的调用被放入该.init_array
部分。地图文件如下所示:
.init_array 0x00007cb8 0x4 libmotor.o
.init_array 0x00007cbc 0x4 libaudio.o
至于
- mips-elf-gcc-4.8.2
- avr-gcc-4.8.1
- msp430-gcc-4.6.3
这些调用进入该.ctors
部分:
.ctors 0x000000009d011508 0x4 libmotor.o
.ctors 0x000000009d01150c 0x4 libaudio.o
编译完成-ffunction-sections -fdata-sections
,链接器得到--gc-sections
.
所有二进制文件都有效,但我想将所有调用放在同一部分(以简化链接器脚本的维护)。
- 为什么有不同的目标部分?
- 是否可以使用命令行选项更改默认部分?
- 如果命令行选项不退出:是否可以在 GCC 编译时定义默认部分?
c - 是否有一种安全的方法来引用仅链接器符号而无需获取 void 表达式的地址?
一个文件有一系列 void 声明void*
,如下所示:
它们仅由链接描述文件作为引用二进制分区的符号提供,如下所示(即指针):
这会产生以下警告:
根据问题 http://stackoverflow.com/questions/27263344 的答案,我已将其更改如下(unsigned long*
无论如何,获取指针的函数都使用):
现在我想到原始定义的大小为零(或未定义),而当前定义没有,并且与问题27263344的答案不同,没有任何逻辑意义上的“真正的基础数据类型”。
本质上,我定义了一个有效的指针,但不指向有效值,因此取消引用是无效的。
有没有更安全或更可取的方法来避免警告,但没有分配空间的想法,不能取消引用?
gcc - gcc 使用的实际默认链接描述文件和设置
我在哪里可以找到 gcc 使用的实际链接器脚本和设置?
我尝试过的事情:
具体来说,让我们考虑一个小程序:empty.c
静态构建它,并查看结果:
注意各个部分,分组为段,并放入具有各种权限的内存区域。
现在让我们尝试尽可能多地了解它是如何进行这种链接的。
但是该脚本虽然很长,但缺少前面列出的大部分导入信息。
它如何知道将哪些部分聚集到不同的负载段中?
没有 PHDRS 命令,虽然 SEGMENT_START 的使用表明该系统在其他地方定义了一些标准段,但没有一个段与关联段一起列出。
此外,它如何知道在哪里加载这些段,或者这些内存区域有什么权限?
没有 MEMORY 命令。同样,如果该系统在其他地方定义了一些标准内存区域,则没有任何部分列出要使用的内存区域。
当我之前看到微控制器的默认链接器脚本时,它们非常详细。但是,此输出表明某处有更多脚本和设置。
这些其他链接描述文件定义和设置存储在哪里?
ld - 从链接描述文件中删除部分时,可执行文件变大
我真的在为链接器脚本苦苦挣扎,所以我决定从一个最小的测试开始并开始调整。但是,即使在我的目标文件中也没有为部分删除默认链接描述文件的行,可能会导致可执行文件急剧增长!
程序:wait_input.S
超小,但足以看到它做某事。现在构建它并从详细输出中获取默认链接器脚本(由 ==== 行描述)。
看一看,我们看到目标文件中只有三个部分(其中只有一个有任何数据),并且生成的可执行文件很小(此时它的 ELF 标头比代码多)。
默认链接描述文件引用了我的目标文件中没有的所有类型的部分,因此我尝试将其缩减,但随后可执行文件的大小突然膨胀。玩了一下,我最终发现只是删除了两行(对于我的目标文件甚至没有的部分!),导致它:
什么!?
有人可以解释一下吗?
我之前使用过微控制器的链接器脚本,它们非常简单。对于 ELF 文件,我真的很难理解它们。似乎没有什么与文档相匹配,并且默认链接描述文件似乎缺少各种重要信息。
linux - 在 --gc-sections 之后更新链接器变量
我在 cortex-a9 板上写了一个小二进制文件,并定义了一个这样的链接器脚本:
但似乎在--gc-sections
工作并删除了未使用的部分之后,__heap_start
仍然是工作之前的值--gc-sections
(我在代码中打印它并检查 ld 标志):
arm-linux-gnueabihf-gcc -mcpu=cortex-a7 -msoft-float -nostdlib -Wl,--gc-sections -Wl,--print-gc-sections -Wl,-Ttext,0x04000000 -T csrvisor.lds - Wl,-Map,binary.map
任何人都知道如何在删除未使用的部分__heap_start
后将值更改为正确的值?--gc-sections
gcc - __isr_vectors variable not found when placed inside a static library
As a spin-off of a previous question (sbrk function not found when placed in a static library):
I'm creating a bare-metal application for the stm32f407 microcontroller, which has an ARM Cortex M4 core. I'm trying to create a static library containing basic stuff like cmsis, the HAL functions, and the interrupt vector table, and link that static library to my main application. However, when the interrupt vector table (which is a variable named __isr_vectors
) is placed inside the static library, the variable does not survive linking.
I can piece together what happens: The linker has an object main.o, and a few libraries. It takes all symbols found in main.o
, and it takes all symbols out of the libraries that are used by main.o
or that are used by other symbols that are already deemed necessary. The __isr_vectors
variable is not yet needed at this stage, since no one references this variable explicitly, so it is thrown out by the linker. Then, the linker searches for all input sections named .isr_vector
in order to create the output section .isr_vector
. However, no symbols survived up to this moment, so that output section is left empty, and my binary is left without an interrupt table.
I know of one trick to get the __isr_vector
to survive: reference it in a dummy function in main.c
. However, this is kinda ugly and error-prone (you can forget to do that when building a new application against the same static library). So here's my question: Is there another way to make the __isr_vector
survive, so that I can just link in my static library and be done with it?
These are the files and steps to reproduce the problem:
vectors.c:
__ attribute__ ((section(".isr_vector"), used)) void* __isr_vectors = 0;
main.c:
void _start(void) {}
link.ld:
MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K }
ENTRY(_start)
SECTIONS { .isr_vector : ALIGN(4) { KEEP(*(.isr_vector)) } >FLASH
}
Commands:
"C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-gcc.exe" -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -std=gnu11 -o main.c.obj -c main.c "C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-gcc.exe" -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -std=gnu11 -o vectors.c.obj -c vectors.c
"C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-gcc.exe" -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -std=gnu11 -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wl,--gc-sections -nostartfiles -Wl,-Tlink.ld -Wl,-Map=test_linker.without_library.map main.c.obj vectors.c.obj -o test_linker.without_library.elf
"C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-ar.exe cq libtest_linker.lib.a vectors.c.obj
"C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-ranlib.exe" libtest_linker.lib.a
"C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2014q4\bin\arm-none-eabi-gcc.exe" -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -std=gnu11 -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wl,--gc-sections -nostartfiles -Wl,-Tlink.ld -Wl,-Map=test_linker.with_library.map main.c.obj -o test_linker.with_library.elf libtest_linker.lib.a
linker-scripts - Gnu 链接器 - 输出节类型
据我所知并且我在链接器文档中阅读过,有 5 种输出节类型:NOLOAD, DSECT, COPY, INFO, OVERLAY
但只解释了其中的 2 种:NOLOAD 和 OVERLAY。COPY
,INFO
并且DSECT
没有解释,在互联网上的任何地方我都可以看到相同的 2 解释和 3 一言不发。任何人都会很好地解释输出部分DSECT
的内容COPY
和INFO
确切的变化?