问题,我想知道为什么链接器在链接的时候没有把链接脚本中符号的地址填充到代码中相应位置?
http://blog.chinaunix.net/uid-122754-id-3144920.html
环境
系统:ubuntu-12.04
编译器:arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
u-boot版本:2012.10
u-boot的command.c中有个函数使用了链接脚本中的符号__u_boot_cmd_end和__u_boot_cmd_start
从反汇编可以看出&__u_boot_cmd_start和&__u_boot_cmd_end的值分别被编译器存放在c5e07700和c5e076fc
c5e076d8: e59f1020 ldr r1, [pc, #32] ; c5e07700 <find_cmd+0x40>
c5e076dc: e59f2018 ldr r2, [pc, #24] ; c5e076fc <find_cmd+0x3c>
查看那两个单元,反汇编代码中给出的是...:
c5e076f8: eaffffc9 b c5e07624 <find_cmd_tbl>
...
c5e07704: c5e2719c strbgt r7, [r2, #412]! ; 0x19c
不死心,将代码下载到板上内存c5e00000处,然后显示内存,可以看到这两个单元的值都为0:
SMDK6410 # md c5e076f8
c5e076f8: eaffffc9 00000000 00000000 c5e2719c .............q..
System.map中可以看到这两个符号的地址
c5e2af74 A __u_boot_cmd_start
c5e2b4b4 A __u_boot_cmd_end
因为在c代码中得不到这两个符号的值,所以在u-boot中执行任何命令都只能得到提示:
Unknown command 'md' - try 'help'
下面给出链接参数,及链接脚本文件。
链接参数:
链接脚本:
http://blog.chinaunix.net/uid-122754-id-3144920.html
环境
系统:ubuntu-12.04
编译器:arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
u-boot版本:2012.10
u-boot的command.c中有个函数使用了链接脚本中的符号__u_boot_cmd_end和__u_boot_cmd_start
1
2
3
4
5
|
cmd_tbl_t *find_cmd (
const
char
*cmd)
{
int
len = &__u_boot_cmd_end - &__u_boot_cmd_start;
return
find_cmd_tbl(cmd, &__u_boot_cmd_start, len);
}
|
从反汇编可以看出&__u_boot_cmd_start和&__u_boot_cmd_end的值分别被编译器存放在c5e07700和c5e076fc
c5e076d8: e59f1020 ldr r1, [pc, #32] ; c5e07700 <find_cmd+0x40>
c5e076dc: e59f2018 ldr r2, [pc, #24] ; c5e076fc <find_cmd+0x3c>
查看那两个单元,反汇编代码中给出的是...:
c5e076f8: eaffffc9 b c5e07624 <find_cmd_tbl>
...
c5e07704: c5e2719c strbgt r7, [r2, #412]! ; 0x19c
不死心,将代码下载到板上内存c5e00000处,然后显示内存,可以看到这两个单元的值都为0:
SMDK6410 # md c5e076f8
c5e076f8: eaffffc9 00000000 00000000 c5e2719c .............q..
System.map中可以看到这两个符号的地址
c5e2af74 A __u_boot_cmd_start
c5e2b4b4 A __u_boot_cmd_end
因为在c代码中得不到这两个符号的值,所以在u-boot中执行任何命令都只能得到提示:
Unknown command 'md' - try 'help'
下面给出链接参数,及链接脚本文件。
链接参数:
1
|
arm-none-eabi-ld -pie -T /design/source/smdk6410/u-boot.lds -Bstatic -Ttext 0xc5e00000 $UNDEF_SYM arch/arm/cpu/arm1176/start.o ...... /design/source/smdk6410/arch/arm/lib/eabi_compat.o -L /design/tools/arm-2011.09/bin/../lib/gcc/arm-none-eabi/4.6.1 -lgcc -Map u-boot.map -o u-boot
|
链接脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
OUTPUT_FORMAT(
"elf32-littlearm"
,
"elf32-littlearm"
,
"elf32-littlearm"
)
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.text)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
.mmudata : { *(.mmudata) }
. = ALIGN(4);
.rel.dyn : {
__rel_dyn_start = .;
*(.rel*)
__rel_dyn_end = .;
}
.dynsym : {
__dynsym_start = .;
*(.dynsym)
}
_end = .;
.bss __rel_dyn_start (OVERLAY) : {
__bss_start = .;
*(.bss)
. = ALIGN(4);
__bss_end__ = .;
}
/DISCARD/ : { *(.dynstr*) }
/DISCARD/ : { *(.dynamic*) }
/DISCARD/ : { *(.plt*) }
/DISCARD/ : { *(.interp*) }
/DISCARD/ : { *(.gnu*) }
}
|
嗯,找到原因了,终于可以睡觉了!
这个是因为ld使用了-pie选项,而程序在运行时并没有进行动态重定位,所在导致符号地址为空。由此推断,当ld使用了-pie选项后,部分符号的地址是在运行过程中确定的,并需要相关代码的配合进行初始化。
这个是因为ld使用了-pie选项,而程序在运行时并没有进行动态重定位,所在导致符号地址为空。由此推断,当ld使用了-pie选项后,部分符号的地址是在运行过程中确定的,并需要相关代码的配合进行初始化。