Search code examples
gcclinkerarmcortex-m

Linker - Data constants replaced by garbage


I'm trying to integrate some third-party library to my project. I compile all my files with no problems, but when i try to add custom library, all constants in this library becomes garbage.

Here is my linker command (split over lines for readability):

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

Here is the objdump for one function, first in library and then in resulting 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

Notice: .word 0x00000004 replaced by .word 0x17ffc880

What can cause such transformation an how can i avoid that?


Solution

  • The 0x00000004 in library is not a real value - it's just an offset which needs to be added to some external symbol. The name of the symbol is stored in so called relocation section and can be displayed by running objdump -Sr.

    The value of the external symbol is unknown until link-time but once the code is fully linked, the offset is replaced with final (so called "absolute") address which happens to be 0x17ffc880 in your case.