[英]Referencing linker-defined symbols in position independent code
I have a module of code compiled for ARM with -fpie, and I'd like to clear the BSS when it is first executed. 我有一个使用-fpie为ARM编译的代码模块,我想在首次执行时清除BSS。 However, when I reference the linker script symbols for the start and end of the BSS section, I get code that contains absolute addresses in local variables.
但是,当我在BSS节的开头和结尾引用链接程序脚本符号时,我得到的代码在局部变量中包含绝对地址。
Here is my assembly entry point: 这是我的程序集入口点:
.section entry_point
code_entry:
# Save arguments to the stack
push {r0-r2}
# Loop over the BSS section, set it all to 0
mov r0, #0
ldr r1, =__bss_start
ldr r2, =__bss_end
loop_bss:
str r0, [r1], #4
cmp r1, r2
blt loop_bss
# Pop arguments from the stack
pop {r0-r2}
# Branch to C code (which will return to caller on its own)
b startPICode
The output is the following: 输出如下:
Disassembly of section .text:
00180000 <code_entry>:
180000: e92d0007 push {r0, r1, r2}
180004: e3a00000 mov r0, #0
180008: e59f1014 ldr r1, [pc, #20] ; 180024 <loop_bss+0x14>
18000c: e59f2014 ldr r2, [pc, #20] ; 180028 <loop_bss+0x18>
00180010 <loop_bss>:
180010: e4810004 str r0, [r1], #4
180014: e1510002 cmp r1, r2
180018: bafffffc blt 180010 <loop_bss>
18001c: e8bd0007 pop {r0, r1, r2}
180020: ea00189f b 1862a4 <startPICode>
180024: 00194360 andseq r4, r9, r0, ror #6
180028: 001950e8 andseq r5, r9, r8, ror #1
Readelf indicates that my ELF file has no relocations. Readelf表示我的ELF文件没有重定位。
Am I correct in thinking that the linker symbols are just integers that will always be absolute addresses? 我是否正确地认为链接器符号只是将始终是绝对地址的整数? If so, is there a way to fix up the addresses at load or execution time?
如果是这样,是否有办法在加载或执行时修正地址? Or is there some other correct way to clear the BSS for this code?
还是有其他一些正确的方法来清除此代码的BSS?
Edit: Adding some readelf -s output. 编辑:添加一些readelf -s输出。 Here's the relevant .S file and everything pertaining to the BSS.
这是相关的.S文件以及与BSS有关的所有信息。
Symbol table '.symtab' contains 812 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00180000 0 SECTION LOCAL DEFAULT 1
2: 0019297c 0 SECTION LOCAL DEFAULT 2
3: 00192994 0 SECTION LOCAL DEFAULT 3
4: 001929b0 0 SECTION LOCAL DEFAULT 4
5: 00193808 0 SECTION LOCAL DEFAULT 5
6: 001942dc 0 SECTION LOCAL DEFAULT 6
7: 00194350 0 SECTION LOCAL DEFAULT 7
8: 00194358 0 SECTION LOCAL DEFAULT 8
9: 0019435c 0 SECTION LOCAL DEFAULT 9
10: 00194360 0 SECTION LOCAL DEFAULT 10
11: 00194360 0 SECTION LOCAL DEFAULT 11
12: 001950e8 0 SECTION LOCAL DEFAULT 12
13: 001970f0 0 SECTION LOCAL DEFAULT 13
14: 00000000 0 SECTION LOCAL DEFAULT 14
15: 00000000 0 SECTION LOCAL DEFAULT 15
16: 00000000 0 SECTION LOCAL DEFAULT 16
17: 00000000 0 SECTION LOCAL DEFAULT 17
18: 00000000 0 SECTION LOCAL DEFAULT 18
19: 00000000 0 SECTION LOCAL DEFAULT 19
20: 00000000 0 SECTION LOCAL DEFAULT 20
21: 00000000 0 SECTION LOCAL DEFAULT 21
22: 00000000 0 SECTION LOCAL DEFAULT 22
23: 00000000 0 SECTION LOCAL DEFAULT 23
24: 00000000 0 FILE LOCAL DEFAULT ABS ./src/entry.o
25: 00180000 0 NOTYPE LOCAL DEFAULT 1 code_entry
26: 00180000 0 NOTYPE LOCAL DEFAULT 1 $a
27: 00180010 0 NOTYPE LOCAL DEFAULT 1 loop_bss
28: 00180024 0 NOTYPE LOCAL DEFAULT 1 $d
29: 00000124 0 NOTYPE LOCAL DEFAULT 17 $d
484: 00194360 0 NOTYPE GLOBAL DEFAULT 10 __sbss_start
525: 00193804 0 NOTYPE GLOBAL DEFAULT 5 __sbss2_end
555: 001950e8 0 NOTYPE GLOBAL DEFAULT 11 __bss_end
565: 00194360 0 NOTYPE GLOBAL DEFAULT 10 __tbss_start
581: 00194360 0 NOTYPE GLOBAL DEFAULT 10 __sbss_end
599: 00193804 0 NOTYPE GLOBAL DEFAULT 5 __sbss2_start
667: 00194360 0 NOTYPE GLOBAL DEFAULT 11 __bss_start
753: 00194360 0 NOTYPE GLOBAL DEFAULT 10 __tbss_end
Your right, the code that you've produced isn't relocatable. 您的权利,您所产生的代码不可重定位。 In order to make it relocatable you're going to explicitly make the addresses of
__bss_start
and __bss_end
relative. 为了使其可重定位,您将显式地使
__bss_start
和__bss_end
的地址相对。 For example: 例如:
.section entry_point
bss_start_rel:
.word __bss_start__ - bss_start_rel
bss_end_rel:
.word __bss_end__ - bss_start_rel
.global code_entry
code_entry:
# Save arguments to the stack
push {r0-r2}
# Loop over the BSS section, set it all to 0
mov r0, #0
adr r3, bss_start_rel
ldr r1, bss_start_rel
ldr r2, bss_end_rel
add r1, r1, r3
add r2, r2, r3
...
The ADR pseudo-instruction results in R3 being loaded with the address of bss_start_rel
using PC relative arithmetic (eg. sub r3, pc, #24
). ADR伪指令导致R3使用PC相对算术(例如
sub r3, pc, #24
)被加载bss_start_rel
的地址。 That's used as base to calculate the location of __bss_start__
and __bss_end__
, who's relative position is stored at bss_start_rel
and bss_start_end
. 这用作计算
__bss_start__
和__bss_end__
位置的__bss_end__
,它们的相对位置存储在bss_start_rel
和bss_start_end
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.