GNU 链接器映射文件给出意外的加载地址

2024-01-05

我正在开发一个嵌入式程序,其中有一个自定义链接器脚本。该程序可以工作,但我注意到链接器在内存中放置几个​​部分的方式可能有问题。

以下是链接描述文件的相关部分:

MEMORY {
    ROM (rx)    : ORIGIN = 0x00100000, LENGTH = 16k
    RAM (rwx)   : ORIGIN = 0x00200000, LENGTH = 4k
}

SECTIONS {
    /* Other sections go here. */
    .data : {
...
    } >RAM AT>ROM

    .bss : {
...
    } >RAM

    .stack : {
...
    } >RAM
...
}

这是 MAP 文件的相关部分:

.data           0x00200040        0x0 load address 0x001003d4
                0x001003d4                __data_load = LOADADDR (.data)
                0x00200040                __data_start = .
 *(.data)
 *(.data*)
                0x00200040                . = ALIGN (0x4)
                0x00200040                _edata = .

.igot.plt       0x00200040        0x0 load address 0x001003d4
 .igot.plt      0x00000000        0x0 ./debug/sam7s_startup.o

.bss            0x00200040        0x0 load address 0x001003d4
                0x00200040                __bss_start__ = .
 *(.bss)
 *(.bss*)
 *(COMMON)
                0x00200040                . = ALIGN (0x4)
                0x00200040                _ebss = .
                0x00200040                __bss_end__ = .
                0x00200040                PROVIDE (end, _ebss)
                0x00200040                PROVIDE (_end, _ebss)
                0x00200040                PROVIDE (__end__, _ebss)

.stack          0x00200040      0x200 load address 0x001003d4
                0x00200040                __stack_start__ = .

因此,从映射文件来看,我认为 .bss 和 .stack 部分正在 ROM 中获取加载地址。我认为这是因为这两行:

.bss 0x00200040 0x0 load address 0x001003d4
.stack 0x00200040 0x200 load address 0x001003d4

这不好,因为它们占用 ROM 空间是没有意义的。 .bss 部分虽然现在是空的,但将包含未初始化的全局变量,这些变量将在代码中设置为零。堆栈也是 RAM 的一部分,将在代码中初始化。因此,这些部分都不需要占用 ROM 空间。

所以我的问题是,阻止 .bss 和 .stack 加载到 ROM 中的正确方法是什么?我是否必须更改 .bss 和 .stack 部分的结尾>RAM to >RAM AT>RAM?这似乎有点多余。

在测试了一些东西之后,我发现了以下内容:

(1) 使用(NOLOAD)属性(例如通过替换.stack : with .stack (NOLOAD) :)仍然会导致映射文件显示 .stack 和 .bss 部分的 ROM 加载地址。

(2) 指定RAM AT>RAM如上所述,确实会阻止映射输出显示 .stack 和 .bss 部分的 ROM 加载地址。

(3) 当映射文件显示 .bss 和 .stack 部分的加载地址时,它们似乎实际上并不占用 ROM 中的空间。 .stack 部分虽然有 0x200 字节长,但似乎实际上并没有占用 ROM 中的空间,即使我为其指定填充值并在链接器脚本中在其后面放置一个部分。链接描述文件中紧随其后的部分不会随堆栈大小的不同而移动。

因此,也许映射文件输出并不意味着我认为的意思,并且 .stack 和 .bss 部分实际上根本没有在 ROM 中给出加载地址。在尝试了一些事情之后,肯定会出现这样的情况。知道为什么映射输出看起来好像给了这些部分 ROM 加载地址,这仍然是很有趣的,特别是当(NOLOAD)用来。这是否只是 LD 生成地图输出文件的一个错误?

也可以看看:了解 GNU 链接器脚本的位置计数器 https://stackoverflow.com/questions/13831462/understanding-the-location-counter-of-gnu-linker-scripts


您正在寻找NOLOAD. See Gnu LD 输出节类型 http://sourceware.org/binutils/docs-2.23.1/ld/Output-Section-Type.html。我现在读了你的整篇文章,我看到你假设了NOLOAD. With NOLOAD,所有地址均已定义。如果您在“C”代码中使用它们,它们将从该地址加载。您必须提供一些启动代码,通常是在汇编程序中,用于清除BSS区域。通常,你并不期望你的stack进行初始化。

A NOLOAD部分就像一个编译/链接 time malloc()。您可以使用内存,但不要指望那里有任何东西。为了BSS你定义__bss_start__ and __bss_end__在链接器脚本中编写一个简短的初始化例程来使用这些变量/地址清除该内存。

Note:一切都显示在地图文件中。它不会显示在生成的二进制文件中,也不会在 ELF 中包含数据。只有部分元信息将保存在 ELF 中。

Edit: The 加载地址地图文件中就像一个用于加载的位置计数器。加载地址在哪里ld是用来放东西的。ld如果它们的大小为零,则并不是真正将它们放在那里。地图输出在语言上并不明确;我知道这很令人困惑,但是ld在创建输出二进制文件时正确执行操作。BSS通常被标记NOLOAD通过目标文件中的 gcc,因此在示例中仅stack部分需要NOLOAD。对于类似的东西stack,实际上并不需要节,只需一组符号声明就可以了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GNU 链接器映射文件给出意外的加载地址 的相关文章

  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • ARM NEON 矢量化失败

    我想在 ARM cortex a9 上启用 NEON 矢量化 但在编译时得到以下输出 未矢量化 不支持相关 stmt D 14140 82 D 14143 77 D 14141 81 这是我的循环 void my mul float32 t
  • 链接器问题 - 未定义的引用

    我的编译器有问题 告诉我有一个 未定义的引用 我想在库中使用的函数 让我分享一些有关该问题的信息 我正在用 gcc 交叉编译 C 语言 我正在调用一个库函数 该函数通过包含的标头访问 其中包含另一个标头 其中包含原型 我已经使用 I 包含了
  • ARM Cortex-M3 启动代码

    我试图了解 STM32 微控制器的 Keil realview v4 附带的初始化代码是如何工作的 具体来说 我试图了解堆栈是如何初始化的 In the 文档 http infocenter arm com help index jsp t
  • 简单的openGL程序无法在ubuntu中链接

    我正在尝试进入 opengl 编程 但无法编译我的第一个非常非常简单的程序 链接过程每次都会失败 我发现这个答案 https stackoverflow com questions 859501 learning opengl in ubu
  • OCUnit 无法识别导入的文件

    我正在我的 iPhone 应用程序上使用 XCode 3 2 3 和 iOS 4 0 上的 OCUnit 进行单元测试 我已成功设置测试环境以适当地通过和失败基本测试 但是当我导入自己的文件 在本例中为 UserAccount h 时 它无
  • 让 TensorFlow 在 ARM Mac 上使用 GPU

    我已经安装了TensorFlow在 M1 上 ARM Mac 根据这些说明 https github com apple tensorflow macos issues 153 一切正常 然而 模型训练正在进行CPU 如何将培训切换到GPU
  • 可以对 Xcode 中的 Arm 架构设置进行一些澄清

    据我了解 iPhone 5将采用新的架构 armv7s 我的项目具有有效的架构armv7 并且有Build Active Architecture Only set to true 由于现在商店中的每个应用程序都是为armv6 and or
  • 未定义的参考错误 - rand

    我正在创建一个命令行 C 测试应用程序 可执行 以便在我的 root Android 设备上运行 该可执行文件使用多个预构建的 C 库 其中之一使用 rand 在链接状态期间我收到错误 rand 的未定义引用 为了检查路径是否设置正确 我尝
  • 如何查看共享库加载的顺序

    给定一个 ELF 二进制文件或共享对象 我如何才能最轻松地查看所需共享库的加载顺序 它们是否按照列出的顺序加载readelf d 我怎样才能最容易地看到所需共享库的加载顺序 Use LD DEBUG LD DEBUG files bin l
  • 在共享库中不使用 PLT 的情况下调用另一个目标文件中的函数?

    我有两个汇编代码 code1 s and code2 s我想从这两个构建一个可重定位 使用 fPIC 开关 共享库 I want code2 s调用一个函数 名为myfun1 其定义在code1 s 当我使用call myfun1 PLT
  • 有什么工具可以了解 Windows 中正在运行的进程的布局(段)?

    我一直很好奇 该进程在内存中到底是什么样子的 其中有哪些不同的部分 部分 程序 在磁盘上 和进程 在内存中 到底是如何相关的 我之前的问题 有关可执行程序 进程 的内存布局的更多信息 https stackoverflow com ques
  • ARM 的内核 Oops 页面错误错误代码

    Oops 之后的错误代码给出了有关 ARM EX 中的恐慌的信息 Oops 17 1 PREEMPT SMP在这种情况下 17 给出了信息 在 x86 中它代表 bit 0 0 no page found 1 protection faul
  • 静态成员变量在可执行文件和 dll 之间不是全局的

    我对链接 DLL 如何工作的知识有点模糊 但我观察到可执行文件中静态成员变量的更改不会更改 DLL 中的相同静态成员变量 这是我的情况 main cpp 静态链接到 mylib lib 在 mylib lib 中 我有以下类 foo h c
  • 包含来自另一个目录的标头时出现 Visual Studio 链接错误

    简短的问题是 如何使用 Visual Studio 创建 编译 运行在不同目录中具有源代码的项目 以下是具体细节 我在一个目录中有一个类定义文件 hpp 和实现文件 cpp 在另一个目录中有一个 main cpp 文件 在 Visual S
  • MIPS 汇编不支持“.set noat”吗?

    目前 我正在学习GNU as 并在 info as 中找到了很多有用的信息 我发现 set noat 在MIPS指定的代码中使用 但是当在 info as 中搜索该指令时 我在节点 alpha指令 中找到了它的解释 但在 MIPS Depe
  • LDR指令如何将常量加载到寄存器中?

    我刚刚读了一本ARM指令书 看到一条指令我无法解释 It says LDR将 32 位常量加载到r0登记 LDR r0 pc const number 8 pc const number DCD 0xff00ffff 我不明白什么 pc c
  • 链接 C 代码时如何判断符号的定义位置

    我面临着链接中特定符号的未定义参考问题 error undefined reference to g queue pop nth 我正在 LOP 和 ARM 平台上工作 我们在两个平台上使用相同的环境 我们的 ARM 构建可以毫无问题地链接
  • 当我尝试在 Armv8 程序集中分配数组时,执行冻结

    所以我正在用汇编语言进行编程 这只是一个简单的代码 这样我就可以学习如何分配数组 以便稍后在 NEON 编程中使用它们 ASM FUNC FPE data balign 8 array skip 80 array1 word 10 20 3
  • 在LPC2148 ARM处理器上创建中断向量的汇编代码

    我最近刚刚开始使用 LPC2148 ARM 处理器 我试图理解一些有关创建中断向量的汇编代码 这是代码 Runtime Interrupt Vectors Vectors b start reset start ldr pc undf un

随机推荐