问题标签 [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 回答
5138 浏览

c - 链接描述文件 .relocate 部分的第一个符号 _srelocate 不正确(GCC 错误?)

问题

我的问题是,当我使用以下旨在将代码放入 RAM 的脚本时,重定位部分会充满虚假数据。

我的问题是:

  1. 为什么_srelocate符号比符号大 4 个字节_etext?他们不应该是一样的吗?

  2. 另外,如果 1. 的答案是否定的,我不应该从_etext + 4to复制_srelocate吗?

背景及相关代码

我正在使用 Atmel ATSAM3N4X 系列处理器(ARM Cortex M3),希望对我的链接器脚本和.relocate部分初始化有所帮助。

原因是_etext符号比_srelocate符号少 4 个字节。

以下链接描述文件是 Atmel Studio 6 生成的默认脚本(如果您想要ram/rom符号位置,请参阅问题的附录)。

我曾经nm查看过符号值是什么,并将它们包括在下面:

现在,Atmel Studio 6 自动生成了我的项目,并给了我一个Reset_Handler()复制该.relocate部分的内容_etext_srelocate清除该.bss部分。该项目带有两个链接器脚本,一个用于基于 FLASH 的执行,一个用于基于 RAM 的代码。默认是基于 FLASH 的代码,但我将其更改为基于 RAM 的链接器脚本(上面提供),然后遇到了问题。

将部分从 FLASH复制.relocate到 RAM 的初始化代码也是自动生成的,我在更改链接器脚本时没有更改它。它看起来像这样:

编辑1:

使用objdump -t CodeFile.elf > CodeFile.symbols,我在我的.relocate部分的开头找到了这个符号,这似乎表明它_srelocate并不真正指向.relocate.

这个符号是什么?

我查了一下并在 GCC 4.7 中发现了这个错误,但无法确定它在我的版本中是否已修复。

我的编译器是arm-none-eabi-gcc并且将它的版本声明为4.7.0...链接器是arm-none-eabi-ld并且它的版本是2.22

编辑2:

我已经对此进行了一些研究,并记录在我提出的这个相关的 SO 问题中。请同时查看它,因为它解释了问题是GCC 错误

附录

链接描述文件的内存布局

0 投票
1 回答
1517 浏览

linker-scripts - 用于 Cortex-M4 的 GNU 链接描述文件中的内存部分

我很失望,因为我找不到有关内存分段的信息。我知道我应该将内存划分为 .text、.data、.bss、.stack 等基本部分,这些部分用于编译程序的目标文件。我知道还有更多其他部分,其中一些是 C 所必需的,而其他部分是 C++ 所必需的。我正在搜索有关链接描述文件中应包含哪些部分的信息?

0 投票
2 回答
7150 浏览

embedded - How can the --add-section switch of OBJCOPY be used?

There are really two questions that revolve around the use of --add-section. The simple one is in the title. Based on my reading, I haven't been able to figure out how one could execute --add-section.

To use add-section, I have to pass a section name. If I use an existing section name the program responds with "can't add section '.data': File in wrong format." Perhaps I just need to pass another parameter. If I use a new section name, which I would prefer to do, I'm warned that "allocated section '.blob' not in segment."

Now, I have gotten my feature to work as I need it to aside from the "not in segment" warning. I'd like to figure out if there is a legitimate way to put this blob into the executable. I would link it in, but that isn't so easy because the data I'm adding is generated from the contents of the executable itself.

The second question is really what I care about. Is there a way to do the following given that the blob cannot be computed until after the link is complete.

  1. Link ELF file
  2. Generate blob from ELF file and other data
  3. Add blob to ELF file so that it is loaded at run-time to the correct location in memory

    objcopy --add-section .blob=blob.o \ --set-section-flags .blob=alloc,contents,load,readonly \ --change-section-address .blob=ADDRESS \ program.elf program.blobbed.elf

I'd be happy to add a section and/or segment to the ELF file as part of the link and insert this blob there. I'm not sure how to do that.

It has occurred to me that I could accomplish this feat with a second link, but objcopy would be cleaner.

  1. Link ELF file
  2. Generate blob from ELF file and other data
  3. Re-link ELF file including new blob.o

UPDATE: This last strategy may be workable as long as the relink doesn't change something in the portion of the program that was produced by the first link. It doesn't on first attempts, but it may be possible to work around it. Hence, the desire to use --add-section to add in this blob instead of going through a second link.

0 投票
2 回答
2549 浏览

c - 链接描述文件:将函数的绝对地址插入到生成的代码中

我有一个与 gcc 的链接器有关的问题。

我正在使用嵌入式东西(PIC32),但 PIC32 的编译器和链接器是基于 gcc 的,因此,“常规”gcc 链接器和 PIC32 链接器的主要内容应该是通用的。

为了节省闪存空间(这在微控制器上通常是不够的),我需要在引导加载程序中放置几个​​大型函数,应用程序应该只通过指针调用这些函数。

所以,我需要在生成的代码中创建向量表。

我正在尝试获取函数的绝对地址并将其写入生成的代码,但仍然出现错误。

在下面的示例中,我试图获取函数的地址_formatted_write

代码:

链接器返回错误:“ unresolvable symbol '_formatted_write' referenced in expression”。

我注意到如果我写了一些垃圾而不是_formatted_write,那么它会返回错误“ undefined symbol .....”,因此,_formatted_write链接器知道。

这让我觉得我应该执行一些额外的步骤以使其“可解决”。但仍然不知道该怎么做。

0 投票
1 回答
645 浏览

linux - 如何强制链接来自特定库的符号?

在 Linux 上链接可执行文件时,我得到一个“未定义的引用”错误,如下所示:

我无法控制“SOMELIB”,但我在自己的一个共享库中确实有该符号symbol。我绝对确定symbol@SOMELIB_1.0与我的库中的符号相同(提供完全相同的功能),实际上甚至源代码也几乎相同。

如何强制/别名symbol@SOMELIB_1.0从我的图书馆链接,而不是从SOMELIB_1.0?我正在考虑链接器脚本中的某种符号版本控制技巧,但我找不到任何解决方案甚至线索。

提前致谢。

0 投票
5 回答
18382 浏览

c++ - 链接器脚本 - 在内存区域的末尾放置一个节

我已经广泛搜索了如何做到这一点,但未能找到答案。

我的内存布局如下:

在堆栈的末尾,我放置了堆。它长大了,堆栈是我正在使用的 ARM 芯片的完整降序堆栈。

现在,我想做的是.persist在我的 ram 内存中放置一个单独的部分,我们称之为它。我希望它位于 RAM 的最末端,并且我想将它编程到我的链接器脚本中。但是,这.persist部分的大小不是由我定义的,而是由编译器根据它包含的符号计算出来的。

到目前为止,我还没有想出一个好的方法来做到这一点。因为我知道 RAM 起始地址和 SIZE,所以如果我知道部分大小,计算部分需要去的位置将是微不足道的。但是,根据GNU 链接器文档(第 74 页),似乎:

SIZEOF(section) 返回指定节的大小(如果已分配该节)。如果在评估时该节尚未分配,则链接器将报告错误。

所以我无法计算出链接描述文件中部分的大小(因为我想在放置/分配它之前计算它的大小)。

有谁知道这样做的好方法?

0 投票
1 回答
1542 浏览

gcc - 加载脚本以加载内存区域顶部的部分

我正在使用 ARM M0 为嵌入式系统开发一个项目。

必须创建一个 ROM 应用程序,其唯一目的是在 rom 中存储内容,并在需要时初始化数据和 bss 部分。

到目前为止的加载脚本是这样的:

我想更改加载脚本,以便将数据和 bss 部分加载到内存区域顶部的 ram 中,而不是底部。

我怎样才能做到这一点?

0 投票
1 回答
1879 浏览

gcc - 为什么 ld 的 KEEP() 不保留我的符号?

通常,通过使用 KEEP(),ld 将符号保留在节中,即使未引用符号也是如此。然而,这不是我的经验。如果未引用符号,我无法创建保留符号的 ld 链接描述文件。

是否有一些先决条件才能起作用?

0 投票
3 回答
12643 浏览

gcc - 如何在 ld 链接描述文件中使用 INCLUDE 命令

我有两个链接器脚本:common.ld它定义了一些符号,以及app.ld使用这些定义来定位这些部分。

如果我只是将这两个文件放在一起,并将其提供给 ld(通过 gcc),它就可以工作。如果我使用INCLUDE命令:

包括 common.ld

我得到错误:

ld.exe:标志中的无效语法

collect2: ld 返回 1 个退出状态

我做错了什么?包含另一个加载脚本的正确语句是什么?


来自http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html#IDX204

包括文件名

此时包括链接描述文件文件名。将在当前目录以及使用 -L 选项指定的任何目录中搜索该文件。您可以嵌套调用 INCLUDE 最多 10 层。

注意:我在 Windows 7 PC 上运行它,使用来自 Code Red 的 arm gcc 工具,完整版:

arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.6.2 20121016 (release) [ARM/embedded-4_6-branch revision 192487

0 投票
1 回答
2117 浏览

c - 将节添加到 GNU 链接器脚本

您好我正在尝试通过以下方式在我的链接器脚本中定义一个自定义部分:

我正在编译一个包含结构的 C 文件,并且我希望该结构始终存储在此 version_section 中。

现在,直到这个阶段一切正常。但是这样生成的部分有标志“AW”但是我需要标志是“A”。

因此,我使用了一个汇编文件,该文件将本节定义为具有这样的“A”标志:

但我仍然看到 version_section 的默认标志,即。AW in readelf

我在这里做错了什么?