问题标签 [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.
c - 在 RAM 初始化之前使用 #defined 值
我正在为 ARM CPU 编写启动代码。没有内部 RAM,但有 1GB 的 DDRAM 连接到 CPU,在初始化之前无法直接访问。代码存储在闪存中,初始化 RAM,然后将自身和数据段复制到 RAM 并在那里继续执行。我的程序是:
目前我的程序无法正常工作,因为寄存器值最终被链接到 RAM,而此时程序试图访问它们只有闪存可用。
我怎样才能更改我的链接描述文件或我的程序,以便这些值在闪存中有它们的地址?有没有办法可以在文本段中包含这些值?
当它们在文件范围内声明时,这些定义的值实际上是全局数据还是静态数据?
编辑:
目标文件与以下链接描述文件链接:
从寄存器分配反汇编:
ld - 链接描述文件中的段加载地址和执行地址
我正在为裸机 ARM 应用程序编写自定义链接器脚本。该应用程序存储在闪存中,目前我有一个启动代码将整个应用程序复制到 SDRAM 中,并继续在 SDRAM 中执行以提高速度。我想修改此脚本以直接从 Flash 运行整个代码,但我无法理解某些元素。
在下面的链接描述文件中,该.ram_data
段有一个执行地址RAM
和一个加载地址ROM
(这两个段都在 SDRAM 中)。据我了解,链接器使用执行地址来对所有与 PC 无关的元素进行符号解析,但是加载地址呢?在裸机 ARM 的上下文中,没有程序加载器之类的东西,链接器也无法影响我在闪存中编写程序的位置,那么它实际上是用来做什么的呢?
同样,链接器如何对运行时的 (rx) 或 (rw) SDRAM 产生任何影响?当我修改内存区域中的这些选项时,它实际上会改变什么吗?
gcc - GCC - 部分有错误的 LMA
我的链接器脚本有问题。.data2、.nonsharedram 和 .bss 部分具有错误的 LMA。它们应该放置在 FLASH 中,而是放置在 SHARED1 和 SHARED2 区域中。
链接器脚本:
来自 objdump:
linker - 对齐链接描述文件中 data/sbss 部分中的所有目标文件
编辑:已解决 - 应用于静态数据部分的链接器脚本属性“SUBALIGN(32)”完全符合我的要求,强制每个链接的目标文件与 32 字节边界对齐,并自动插入填充。
我正在缓存不连贯架构上构建多程序基准测试,该架构由重命名并链接在一起的 EEMBC 套件的多个实例组成。
问题是库在可写数据段中没有对齐缓存线,我在这里遇到数据损坏(通过连贯模拟中的缓存线抖动来证明)。
例如,0x7500 处的缓存行在 Viterb0 和 Viterb1 上运行的内核之间共享,映射输出表明这是库 0 运行到库 1 开始的缓存行的位置:
我需要将各个数据段中链接的每个目标文件对齐到32字节的边界,我只知道如何对齐整个部分,当前的.bss部分是:
任何帮助在这里将不胜感激,使用填充重建库并不是我真正想要考虑的选项,因为我希望这个更强大的解决方案用于该平台上的未来链接目的。
mips - 使用 GNU ld,如何强制指定特定(外部)符号的地址而不会出现“重定位截断”错误?
我有两个函数,a()
和b()
,它们都有特定的、固定的加载/运行时地址。我正在编译a()
自己,而b()
已经提供(例如在 ROM 中)。
该文件a.c
如下:
这将生成以下汇编代码:
所以它在那里放置了一个 26 位的重定位b()
(调用的目标是从调用指令本身的地址开始的 26 位偏移量)。假设 和 的具体地址a
分别b
为 0x80001000 和 0x80002000。那应该没问题;b
很容易触手可及a
。
所以在我的链接器脚本中,我有这样的东西:
但是,a.o
与此脚本链接会给我以下错误:
据推测,这是因为链接器试图将完整的 32 位值 ( 0x80002000
) 放入 26 位空间中以供跳转目标使用。我的链接器脚本有什么问题?
c - 与另一个启动文件链接
我正在尝试使用STARTUP
LD 脚本中的指令将程序与我自己的启动文件链接:
GCC 驱动程序用于链接程序(不打扰 libgcc 等库路径):
不幸的是,它只适用于为 powerpc 目标编译的 GCC,而 arm 或 i686 目标则不能并且仍然在 collect2 中包含 crt0.o。例如:
给我:
因此:
似乎该STARTUP
指令被完全忽略(除非指定该指令,否则 powerpc 目标也使用其默认 crt0 STARTUP
)并且无法禁用默认 crt0。
是否有一种可移植的方式来链接另一个启动文件?
我的启动文件使用libgcc
函数(调用ctors和dtors),所以需要crtbegin.o
,crtend.o
等等,所以我想避免-nostartfiles
禁用的选项crt*.o
- 我只需要禁用crt0.o
。
谢谢
c++ - 如何将变量放在节的末尾(使用 GCC)
我想在其内存部分的末尾放置一个特定的变量。
所以如果我有:
文件 1.cpp:
在另一个 file2.cpp 中:
我怎么能强迫var2
在最后mysection
?
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部分中的指定文件被正确映射吗?
如何指定链接器将归档文件中的某些目标文件映射到特定区域?这甚至可能吗?
c - 是否可以在 C 代码中将链接描述文件符号地址作为编译时间常数值?
我想获取程序结尾的地址,并在编译/链接器时检查我是否有足够的空间,在代码之后,在执行时放置一些随机数据。
但是由于 PROVIDE 关键字提供的符号就像 C 代码中的普通变量一样,我无法在编译时验证它。
在链接器脚本中,我有符号:
所以我可以使用这个符号来获取我的代码末尾的地址:
如果我假设结束地址为 0xffff,我可以计算可用内存:
我正在考虑使用 gcc 4.6 中提供的 _Static_assert(cond, message) 检查可用内存
我的问题是:宏 AVAILABLE_MEM 不是在编译时计算的,所以我得到了错误:
有没有办法直接在标签中或以其他方式提供 __data_end_rom 地址?
我知道我无法在编译时得到它,因为符号只会在链接器时被链接,所以有什么方法可以让链接器失败?
我可以直接在链接器脚本中检查这一点,但我不喜欢这样做,因为 SIZE_I_WANT_TO_ASSURE 是从配置头中的其他宏计算的另一个宏。
c - 在 GNU 链接描述文件中,带有空输入节列表的“节”命令有什么影响?
在 LD 链接器脚本中,我在该部分中有以下片段SECTIONS
:
where__BUFFER_LOCATION_
被定义到某个地址并EXTERNAL_MEM
在MEMORY
section 中定义。
在C
程序中,我有一个全局缓冲区声明为:
可以看出,链接描述文件没有提到任何名为 的输入节BUFFER
,但输出节是这样命名的。
编译程序时,我看到链接器将缓冲区放置在假定的地址 ( BUFFER_LOCATION
) 中,尽管 LDF 中没有定义输入部分。当我attribute
从源中删除时,缓冲区被放置在一个完全不同的地址中。
因此,我假设默认情况下,“输入节描述”类型的输出节命令会将输出节的名称隐式添加到输入节列表中,除非在其他地方定义。但是,阅读手册,我找不到这种行为的描述。
我错过了什么,还是“未记录的功能”?