链接器 - 数据常量被垃圾替换
Linker - Data constants replaced by garbage
我正在尝试将一些第三方库集成到我的项目中。
我编译我所有的文件都没有问题,但是当我尝试添加自定义库时,这个库中的所有常量都变成了垃圾。
这是我的链接器命令(为了便于阅读而拆分成几行):
arm-none-eabi-gcc
-Wall
-Wextra
-Wno-unused-but-set-variable
-mthumb
-mfloat-abi=soft
-mcpu=cortex-m4
-ffunction-sections
-fdata-sections
-ffreestanding
-g -ggdb -gdwarf-2 -g3
-Ibuild/ -Iinc/ -ICMSIS/ -I../lib/ -I.
-fverbose-asm
-DSTM32F407xx
-Wl,--gc-sections
-Wl,-Map=build/output.map
--specs=nosys.specs
-TLinkerScript.ld
-o build/main.elf
build/main.o {tons of o-files} ../lib/sdk.a
这是一个函数的 objdump,首先在库中,然后在生成的 ELF 中:
arm-none-eabi-objdump -S ../lib/sdk.a build/main.elf | grep "<some_function>:" -A 9
00000000 <some_function>:
0: 4b02 ldr r3, [pc, #8] ; (c <some_function+0xc>)
2: 4a03 ldr r2, [pc, #12] ; (10 <some_function+0x10>)
4: 447b add r3, pc
6: 589b ldr r3, [r3, r2]
8: 6018 str r0, [r3, #0]
a: 4770 bx lr
c: 00000004 .word 0x00000004
10: 00000000 .word 0x00000000
08004b28 <some_function>:
8004b28: 4b02 ldr r3, [pc, #8] ; (8004b34 <some_function+0xc>)
8004b2a: 4a03 ldr r2, [pc, #12] ; (8004b38 <some_function+0x10>)
8004b2c: 447b add r3, pc
8004b2e: 589b ldr r3, [r3, r2]
8004b30: 6018 str r0, [r3, #0]
8004b32: 4770 bx lr
8004b34: 17ffc880 .word 0x17ffc880
8004b38: 00000164 .word 0x00000164
注意事项:
.word 0x00000004
取而代之
.word 0x17ffc880
什么会导致这种转变,我该如何避免?
库中的 0x00000004
不是实际值 - 它只是一个需要添加到某些外部符号的偏移量。符号的名称存储在所谓的重定位部分中,可以通过 运行 objdump -Sr
.
显示
外部符号的值在 link 之前是未知的,但一旦代码完全 linked,偏移量将替换为最终(所谓的“绝对”)地址,这发生了在你的情况下 0x17ffc880
。
我正在尝试将一些第三方库集成到我的项目中。 我编译我所有的文件都没有问题,但是当我尝试添加自定义库时,这个库中的所有常量都变成了垃圾。
这是我的链接器命令(为了便于阅读而拆分成几行):
arm-none-eabi-gcc
-Wall
-Wextra
-Wno-unused-but-set-variable
-mthumb
-mfloat-abi=soft
-mcpu=cortex-m4
-ffunction-sections
-fdata-sections
-ffreestanding
-g -ggdb -gdwarf-2 -g3
-Ibuild/ -Iinc/ -ICMSIS/ -I../lib/ -I.
-fverbose-asm
-DSTM32F407xx
-Wl,--gc-sections
-Wl,-Map=build/output.map
--specs=nosys.specs
-TLinkerScript.ld
-o build/main.elf
build/main.o {tons of o-files} ../lib/sdk.a
这是一个函数的 objdump,首先在库中,然后在生成的 ELF 中:
arm-none-eabi-objdump -S ../lib/sdk.a build/main.elf | grep "<some_function>:" -A 9
00000000 <some_function>:
0: 4b02 ldr r3, [pc, #8] ; (c <some_function+0xc>)
2: 4a03 ldr r2, [pc, #12] ; (10 <some_function+0x10>)
4: 447b add r3, pc
6: 589b ldr r3, [r3, r2]
8: 6018 str r0, [r3, #0]
a: 4770 bx lr
c: 00000004 .word 0x00000004
10: 00000000 .word 0x00000000
08004b28 <some_function>:
8004b28: 4b02 ldr r3, [pc, #8] ; (8004b34 <some_function+0xc>)
8004b2a: 4a03 ldr r2, [pc, #12] ; (8004b38 <some_function+0x10>)
8004b2c: 447b add r3, pc
8004b2e: 589b ldr r3, [r3, r2]
8004b30: 6018 str r0, [r3, #0]
8004b32: 4770 bx lr
8004b34: 17ffc880 .word 0x17ffc880
8004b38: 00000164 .word 0x00000164
注意事项:
.word 0x00000004
取而代之
.word 0x17ffc880
什么会导致这种转变,我该如何避免?
库中的 0x00000004
不是实际值 - 它只是一个需要添加到某些外部符号的偏移量。符号的名称存储在所谓的重定位部分中,可以通过 运行 objdump -Sr
.
外部符号的值在 link 之前是未知的,但一旦代码完全 linked,偏移量将替换为最终(所谓的“绝对”)地址,这发生了在你的情况下 0x17ffc880
。