链接脚本的学习

网上有个英文的官方文档:

ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_mono/ld.html#SEC21

 

1、主要的格式

SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}

(1)secname:段名

(2)start:起始地址;运行时地址;重定位地址

(3)AT(ldadr) :load addr;加载地址。不写的时候,load addr = runtime addr

 

2、代码重定位与位置无关码

问:怎么写位置无关的程序呢?

答:使用位置无关码!不使用绝对地址!最根本的方法就是看反汇编。

 

a. 调用程序时,使用B/BL相对跳转命令

例子:

30 3000005c: eb000106 bl 3000047c <sdram_init>
31 30000060: e3a01000 mov r1, #0 ; 0x0
32 30000064: e59f204c ldr r2, [pc, #76] ; 300000b8 <.text+0xb8>
33 30000068: e59f304c ldr r3, [pc, #76] ; 300000bc <.text+0xbc>

我们看bl 3000047c,这个不是跳到3000047c内存地址的地方,而是跳到0x47c。

 

b. 重定位之前,不可以使用绝对地址,因为这时候绝对位置的地方还没有内容,比如:

  不可以访问全局变量/静态变量

  不可以访问数组(rodata, data)

c. 重定位之后,使用绝对跳转命令跳到runtime addr,比如;

  ldr pc, =main

这样就可以调到绝对地址为main的地方

 

3、C函数中怎么使用lds链接脚本中的变量abc呢?

a. 在C函数中声明该变量为extern类型,比如:

  extern int abc;

b. 使用时,要取址,比如:

  int *p = &abc;   //p的值即为lds文件中的abc的值

 

posted @ 2018-04-11 23:42  伊斯科明  阅读(178)  评论(0编辑  收藏  举报