按应用程序访问链接程序脚本中定义的符号 [英] Access symbols defined in the linker script by application

查看:78
本文介绍了按应用程序访问链接程序脚本中定义的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的链接描述文件中,我定义了两个符号

In my linker script file, I have defined two symbols

define symbol _region_RAM_start__     = 0xC0000000;
define symbol _region_RAM_end__       = 0xC00fffff; 

然后我将它们导出,如下图所示

and then I have exported them as well as shown below

export symbol _region_RAM_start__;
export symbol _region_RAM_end__;

从应用代码中,我尝试访问这些符号

From the applciation code, I try to access these symbols

extern const unsigned int _region_RAM_start__;
extern const unsigned int _region_RAM_end__;
....
int GetRAMSize()
{
    int size = 0;
    unsigned int address_1 = _region_RAM_start__;
    unsigned int address_2 = _region_RAM_end__;
    size = address_2 - address_1 + 1U;
    return size;
}

现在,我希望返回值为0x00100000,但是,我得到的只是0.因此,当我转向调试器时,我注意到 _region_RAM_start__ 和 _region_RAM_end__ 的值分别为 0xC0000000 和 0xC00fffff,但 address_1 和 address_2 的值为 0.

Now, I expected the return value to be 0x00100000, however, all I get is 0. So, when I turned to the debugger, I noticed that _region_RAM_start__ and _region_RAM_end__ have the values 0xC0000000 and 0xC00fffff respectively, but address_1 and address_2 have the value 0.

编译器优化设置为无".这已经困扰了我一段时间了.

The compiler optimization is set to "None". This has been bugging me for a while now. Is there something very obvious I am missing here (other than I should not be doing this in the first place)?

解决方案感谢n.m.寻找答案

Solution Thanks to n.m. for the answer

  unsigned int address_1 = (unsigned int) (&_region_RAM_start__);

否则address_1和address_2都包含垃圾值(即分别在地址0xC0000000和0xC00fffff可用的值,但从此代码的角度来看是垃圾)

Otherwise address_1 and address_2 both contain garbage values (i.e. values available at the address 0xC0000000 and 0xC00fffff respectivly, but garbage from the point of view of this code)

推荐答案

有点老了,但我还是会回答它的.

That's a bit old but i will answer it anyways…

ld 手册:

从源代码访问链接器脚本定义的变量是不直观.特别是链接脚本符号不是等效于高级语言中的变量声明,相反,它是一个没有值的符号.

Accessing a linker script defined variable from source code is not intuitive. In particular a linker script symbol is not equivalent to a variable declaration in a high level language, it is instead a symbol that does not have a value.

在进一步介绍之前,重要的是要注意编译器通常将源代码中的名称转换为不同的名称当它们存储在符号表中时.例如,Fortran编译器通常在下划线之前或后面加上C ++执行大量的名称处理.因此可能会有一个在变量名中使用的变量名之间存在差异源代码和与定义的变量相同的名称在链接描述文件中.例如在C中,一个链接描述文件变量可能称为:

Before going further, it is important to note that compilers often transform names in the source code into different names when they are stored in the symbol table. For example, Fortran compilers commonly prepend or append an underscore, and C++ performs extensive name mangling. Therefore there might be a discrepancy between the name of a variable as it is used in source code and the name of the same variable as it is defined in a linker script. For example in C a linker script variable might be referred to as:

extern int foo;

但是在链接描述文件中,它可能定义为:

But in the linker script it might be defined as:

_foo = 1000;

在其余示例中,假定没有名称转变已经发生.

In the remaining examples however it is assumed that no name transformation has taken place.

以高级语言(例如C)声明符号时,有两件事发生.首先是编译器保留程序内存中有足够的空间来保存符号.第二个是编译器创建一个条目在程序的符号表中,该表保存符号的地址.即符号表包含内存块的地址持有符号的值.因此,例如下面的C声明,在文件范围内:

When a symbol is declared in a high level language such as C, two things happen. The first is that the compiler reserves enough space in the program's memory to hold the value of the symbol. The second is that the compiler creates an entry in the program's symbol table which holds the symbol's address. ie the symbol table contains the address of the block of memory holding the symbol's value. So for example the following C declaration, at file scope:

int foo = 1000;

在符号表中创建一个名为"foo"的条目.此项保存一个 int 大小的内存块的地址,其中最初存储的数字是1000.

creates a entry called "foo" in the symbol table. This entry holds the address of an int sized block of memory where the number 1000 is initially stored.

当程序引用符号时,编译器将生成代码首先访问符号表以查找地址符号的存储块,然后编码以从中读取值内存块.所以:

When a program references a symbol the compiler generates code that first accesses the symbol table to find the address of the symbol's memory block and then code to read the value from that memory block. So:

foo = 1;

在符号表中查找符号foo,获取地址与此符号关联,然后将值 1 写入该地址.而:

looks up the symbol foo in the symbol table, gets the address associated with this symbol and then writes the value 1 into that address. Whereas:

int * a = & foo;

在符号表中查找符号foo,获取其地址然后将此地址复制到关联的内存块中带有变量"a".

looks up the symbol foo in the symbol table, gets it address and then copies this address into the block of memory associated with the variable "a".

链接器脚本符号声明创建一个条目在符号表中,但不要为其分配任何内存.因此它们是没有值的地址.因此,例如链接器脚本定义:

Linker scripts symbol declarations, by contrast, create an entry in the symbol table but do not assign any memory to them. Thus they are an address without a value. So for example the linker script definition:

foo = 1000;

在名为@samp {foo}的符号表中创建一个条目,该条目保存内存位置1000的地址,但没有特殊存储地址为1000.这意味着您无法访问以下地址的 value 链接程序脚本定义的符号-它没有值-您可以做的所有事情是使用链接脚本定义的符号的地址.

creates an entry in the symbol table called @samp{foo} which holds the address of memory location 1000, but nothing special is stored at address 1000. This means that you cannot access the value of a linker script defined symbol - it has no value - all you can do is use the address of a linker script defined symbol.

因此,当您在源代码中使用链接器脚本定义的符号时代码,您应该始终使用符号的地址,并且永远不要尝试使用其值.例如,假设您要复制称为.ROM的内存部分的内容名为.FLASH,链接脚本包含以下声明:

Hence when you are using a linker script defined symbol in source code you should always take the address of the symbol, and never attempt to use its value. For example suppose you want to copy the contents of a section of memory called .ROM into a section called .FLASH and the linker script contains these declarations:

start_of_ROM   = .ROM;
end_of_ROM     = .ROM + sizeof (.ROM);
start_of_FLASH = .FLASH;

然后执行复制的C源代码为:

Then the C source code to perform the copy would be:

extern char start_of_ROM, end_of_ROM, start_of_FLASH;

memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM);

请注意&"的使用运营商.他们是对的.

Note the use of the "&" operators. They are correct.

这篇关于按应用程序访问链接程序脚本中定义的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆