问题标签 [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.

0 投票
2 回答
364 浏览

c - 在 RAM 初始化之前使用 #defined 值

我正在为 ARM CPU 编写启动代码。没有内部 RAM,但有 1GB 的 DDRAM 连接到 CPU,在初始化之前无法直接访问。代码存储在闪存中,初始化 RAM,然后将自身和数据段复制到 RAM 并在那里继续执行。我的程序是:

目前我的程序无法正常工作,因为寄存器值最终被链接到 RAM,而此时程序试图访问它们只有闪存可用。

我怎样才能更改我的链接描述文件或我的程序,以便这些值在闪存中有它们的地址?有没有办法可以在文本段中包含这些值?

当它们在文件范围内声明时,这些定义的值实际上是全局数据还是静态数据?

编辑:

目标文件与以下链接描述文件链接:

从寄存器分配反汇编:

0 投票
2 回答
6263 浏览

ld - 链接描述文件中的段加载地址和执行地址

我正在为裸机 ARM 应用程序编写自定义链接器脚本。该应用程序存储在闪存中,目前我有一个启动代码将整个应用程序复制到 SDRAM 中,并继续在 SDRAM 中执行以提高速度。我想修改此脚本以直接从 Flash 运行整个代码,但我无法理解某些元素。

在下面的链接描述文件中,该.ram_data段有一个执行地址RAM和一个加载地址ROM(这两个段都在 SDRAM 中)。据我了解,链接器使用执行地址来对所有与 PC 无关的元素进行符号解析,但是加载地址呢?在裸机 ARM 的上下文中,没有程序加载器之类的东西,链接器也无法影响我在闪存中编写程序的位置,那么它实际上是用来做什么的呢?

同样,链接器如何对运行时的 (rx) 或 (rw) SDRAM 产生任何影响?当我修改内存区域中的这些选项时,它实际上会改变什么吗?

0 投票
1 回答
988 浏览

gcc - GCC - 部分有错误的 LMA

我的链接器脚本有问题。.data2、.nonsharedram 和 .bss 部分具有错误的 LMA。它们应该放置在 FLASH 中,而是放置在 SHARED1 和 SHARED2 区域中。

链接器脚本:

来自 objdump:

0 投票
2 回答
2256 浏览

linker - 对齐链接描述文件中 data/sbss 部分中的所有目标文件

编辑:已解决 - 应用于静态数据部分的链接器脚本属性“SUBALIGN(32)”完全符合我的要求,强制每个链接的目标文件与 32 字节边界对齐,并自动插入填充。


我正在缓存不连贯架构上构建多程序基准测试,该架构由重命名并链接在一起的 EEMBC 套件的多个实例组成。

问题是库在可写数据段中没有对齐缓存线,我在这里遇到数据损坏(通过连贯模拟中的缓存线抖动来证明)。

例如,0x7500 处的缓存行在 Viterb0 和 Viterb1 上运行的内核之间共享,映射输出表明这是库 0 运行到库 1 开始的缓存行的位置:

我需要将各个数据段中链接的每个目标文件对齐到32字节的边界,我只知道如何对齐整个部分,当前的.bss部分是:

任何帮助在这里将不胜感激,使用填充重建库并不是我真正想要考虑的选项,因为我希望这个更强大的解决方案用于该平台上的未来链接目的。

0 投票
1 回答
1352 浏览

mips - 使用 GNU ld,如何强制指定特定(外部)符号的地址而不会出现“重定位截断”错误?

我有两个函数,a()b(),它们都有特定的、固定的加载/运行时地址。我正在编译a()自己,而b()已经提供(例如在 ROM 中)。

该文件a.c如下:

这将生成以下汇编代码:

所以它在那里放置了一个 26 位的重定位b()(调用的目标是从调用指令本身的地址开始的 26 位偏移量)。假设 和 的具体地址a分别b为 0x80001000 和 0x80002000。那应该没问题;b很容易触手可及a

所以在我的链接器脚本中,我有这样的东西:

但是,a.o与此脚本链接会给我以下错误:

据推测,这是因为链接器试图将完整的 32 位值 ( 0x80002000) 放入 26 位空间中以供跳转目标使用。我的链接器脚本有什么问题?

0 投票
2 回答
5114 浏览

c - 与另一个启动文件链接

我正在尝试使用STARTUPLD 脚本中的指令将程序与我自己的启动文件链接:

GCC 驱动程序用于链接程序(不打扰 libgcc 等库路径):

不幸的是,它只适用于为 powerpc 目标编译的 GCC,而 arm 或 i686 目标则不能并且仍然在 collect2 中包含 crt0.o。例如:

给我:

因此:

似乎该STARTUP指令被完全忽略(除非指定该指令,否则 powerpc 目标也使用其默认 crt0 STARTUP)并且无法禁用默认 crt0。

是否有一种可移植的方式来链接另一个启动文件?

我的启动文件使用libgcc函数(调用ctors和dtors),所以需要crtbegin.ocrtend.o等等,所以我想避免-nostartfiles禁用的选项crt*.o- 我只需要禁用crt0.o

谢谢

0 投票
2 回答
4879 浏览

c++ - 如何将变量放在节的末尾(使用 GCC)

我想在其内存部分的末尾放置一个特定的变量。

所以如果我有:

文件 1.cpp:

在另一个 file2.cpp 中:

我怎么能强迫var2在最后mysection

0 投票
1 回答
3864 浏览

gcc - GCC 链接器 - 为存档文件中包含的代码指定输出部分

背景

我正在使用GNU Tools for ARM Embedded Processors编译器,它是一个 GCC 编译器。我目前在 Windows 环境中工作。

我正在构建一个相对较大的项目,并且已经成功编译了所有源代码,但是在链接阶段面临挑战。这个特定平台作为两个独立的 RAM 区域,我需要将目标代码的某些部分映射到特定区域。

我想我应该能够使用链接器脚本,例如:

但是,我的问题是编译器输出的是 .lib 文件(档案)而不是 .obj 文件。正在使用以下语法在所有存档文件的当前目录中调用链接器:

ld.exe --library-path=C:\SomePath\lib --Map C:\Somepath\bin\mapfile.map --script=C:\Somepath\bin\linkscript.ldf -( file1.lib file2.lib ... -)

即使 .lib 文件包含对 .obj 文件的引用,链接器仍会抱怨它找不到该文件,someLib.obj可能是因为它没有给出完整路径来了解映射所指的文件。

在链接器脚本中为链接器提供完整路径似乎也不起作用;指定目标文件中包含的符号仍显示在内存的第一部分。

问题

示例链接描述文件中的语法是否有效?第一部分中的通配符会阻止section部分中的指定文件被正确映射吗?

如何指定链接器将归档文件中的某些目标文件映射到特定区域?这甚至可能吗?

0 投票
3 回答
9300 浏览

c - 是否可以在 C 代码中将链接描述文件符号地址作为编译时间常数值?

我想获取程序结尾的地址,并在编译/链接器时检查我是否有足够的空间,在代码之后,在执行时放置一些随机数据。

但是由于 PROVIDE 关键字提供的符号就像 C 代码中的普通变量一样,我无法在编译时验证它。

在链接器脚本中,我有符号:

所以我可以使用这个符号来获取我的代码末尾的地址:

如果我假设结束地址为 0xffff,我可以计算可用内存:

我正在考虑使用 gcc 4.6 中提供的 _Static_assert(cond, message) 检查可用内存

我的问题是:宏 AVAILABLE_MEM 不是在编译时计算的,所以我得到了错误:

有没有办法直接在标签中或以其他方式提供 __data_end_rom 地址?

我知道我无法在编译时得到它,因为符号只会在链接器时被链接,所以有什么方法可以让链接器失败?

我可以直接在链接器脚本中检查这一点,但我不喜欢这样做,因为 SIZE_I_WANT_TO_ASSURE 是从配置头中的其他宏计算的另一个宏。

0 投票
1 回答
458 浏览

c - 在 GNU 链接描述文件中,带有空输入节列表的“节”命令有什么影响?

在 LD 链接器脚本中,我在该部分中有以下片段SECTIONS

where__BUFFER_LOCATION_被定义到某个地址并EXTERNAL_MEMMEMORYsection 中定义。

C程序中,我有一个全局缓冲区声明为:

可以看出,链接描述文件没有提到任何名为 的输入节BUFFER,但输出节是这样命名的。

编译程序时,我看到链接器将缓冲​​区放置在假定的地址 ( BUFFER_LOCATION) 中,尽管 LDF 中没有定义输入部分。当我attribute从源中删除时,缓冲区被放置在一个完全不同的地址中。

因此,我假设默认情况下,“输入节描述”类型的输出节命令会将输出节的名称隐式添加到输入节列表中,除非在其他地方定义。但是,阅读手册,我找不到这种行为的描述。

我错过了什么,还是“未记录的功能”?