GCC(NOLOAD)-directive导致错误的内存映射

时间:2018-02-13 10:08:11

标签: c gcc memory attributes ld

我正在与GCC(MIPS)合作。 以下是我的.ld文件中的相关部分。

MEMORY
{
   MEMORY_1                : ORIGIN = 0xB014D000,          N
   ....
   MEMORY_N                : ORIGIN = 0x9C00C800,          LENGTH = X*K
}
SECTIONS
{
   ....
 .my_section  ALIGN(32)           (NOLOAD)  : { } > MEMORY_1
   ....
}

代码中全局缓冲区的定义:

static U32 __attribute__((section(".my_section"))) gBuffer[size];

我预计gBuffer[]地址位于MEMORY_1,但地址为0x9c0*****,即MEMORY_N。 为什么?我该如何解决?

修改 我发现删除NOLOAD指令后缓冲区位于MEMORY_1

  

(NOLOAD)指令将标记在运行时不加载的部分。链接器将正常处理该部分,但会对其进行标记,以便程序加载器不会将其加载到内存中。

我需要在这里使用(NOLOAD)指令。对所描述的行为有什么解释? 如果不将缓冲区移动到意外内存,我如何使用NOLOAD?

EDIT2: ld文件看起来像这样(根据Matthias的建议):

_gBuffer_1 = address(MEMORY_1),
_gBuffer_2 = address(MEMORY_1) + _gBuffer_1_size,
_gbuffer_3 = address(MEMORY_1) + _gBuffer_1_size + _gBuffer_2_size.......
必须在ld文件中定义

_gBuffer_i_size。 我的代码和很多部分都有很多这样的缓冲区。 现在,每当有人希望添加新缓冲区或更改现有缓冲区(删除它或更改其大小......)时,他必须通过ld文件并重新计算地址,这就是为什么我发现建议的方法不易维护。 最初的方法允许定义缓冲区,在程序员希望的每个部分中轻松找到它,并将其余的工作留给链接器。添加(NOLOAD)指令后引发的问题。

2 个答案:

答案 0 :(得分:1)

您可以完全避免使用gcc属性。只需在链接器文件中提供符号:

_gBuffer = 0xB014D000;

然后你可以将缓冲区声明为extern:

extern U32 gBuffer[size];

现在,链接器应该将extern声明绑定到给定的地址。

答案 1 :(得分:1)

我们只是遇到了同样的问题。我们的解决方法是增加一个间接层:

<TextBox Text="This control is focused on startup">
    <dxmvvm:Interaction.Behaviors>
        <dxmvvm:FocusBehavior/>
    </dxmvvm:Interaction.Behaviors>
</TextBox>

不知道为什么直接使用它会起作用。