为 GNU .ld 脚本起源定义符号常量

问题描述 投票:0回答:2

我正在创建一个 GNU .ld 链接器脚本,并且想以符号方式定义某些内存部分的起源。 以下不起作用:

BASE_ADDR = 0x4000;

MEMORY
{
  m_interrupts        (RX) : ORIGIN = BASE_ADDR, LENGTH = 0x0200
  m_bootloader_config (RX) : ORIGIN = BASE_ADDR + 0x3C0, LENGTH = 0x0040
  m_text              (RX) : ORIGIN = BASE_ADDR + 0x400, LENGTH = 0x10000 - (BASE_ADDR + 0x400)
  m_data              (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x4000
}

这会导致以下错误:

Invoking: Cross ARM C++ Linker
../MKL27Z64xxx4_flash.ld:67: nonconstant expression for origin
collect2: error: ld returned 1 exit status

错误指的是以下行:

m_interrupts        (RX) : ORIGIN = BASE_ADDR, LENGTH = 0x0200

令我困惑的是,

BASE_ADDR
对我来说看起来相当恒定。 我需要调用一些特殊语法来说服
ld
BASE_ADDR
是常量吗?

c linker gnu
2个回答
1
投票

LD 手册指出,对于内存:

“origin 是内存区域起始地址的表达式。在执行内存分配之前,该表达式必须计算为常量,这意味着您不能使用任何与节相关的符号。关键字 ORIGIN 可以缩写为 org 或o(但不是,例如 ORG)“

表达式:

BASE_ADDR = 0X4000;
是节相对符号

以下文字也适用:

“然而,其他值(例如符号值)直到存储分配之后才知道或需要。当其他信息(例如输出节的大小)可用于符号赋值表达式时,稍后会评估这些值。 ”

建议在内存分配中使用硬编码值


0
投票

截至今天,这个问题似乎已得到解决,较新版本的

ld
能够做到这一点。

新功能跟踪如下: https://sourceware.org/bugzilla/show_bug.cgi?id=4643

© www.soinside.com 2019 - 2024. All rights reserved.