Search code examples
linkerldlinker-scripts

Import symbols from an existing binary in a linker script


I am creating a binary for a microprocessor with flash and ram. The regular build process uses a linker script to declare where different sections should go and also exports parameters to the code, like which part of the ram can be used for heap.

For better development and updatability I want to add a custom bootloader at the beginning of the binary. However this leads to the need to add "magic constants" to the linker script of the main binary. E.g. the binary cannot start at the beginning of the flash anymore, but only a few kilobytes later, depending on the codesize of the bootloader. Additionally I want to reference some flash regions of the bootloader from the main binary.

As a primitive, I would like to be able to load symbols from an existing (.elf-)binary for usage in a linker script without including any payload data from the other binary, but that does not seem to be possible.

So after linking I would like to have 2 binaries:

  • bootloader.elf (uses flash 0x10000000 - 0x1004a000)
  • application.elf (uses flash 0x1004a000 - 0x10080000 and references other symbols in bootloader.elf)

Is this possible without hardcoding the addresses inside the linker script for application.elf (and needing to change them whenever I change something in the bootloader)?

The INPUT linker-script command only accepts object files, so that command is not useful, and I can't find any other useful command there.

In general, it feels like I'm trying to solve this problem with the wrong tools.


Solution

  • ld offers an option to load just the symbols of a binary to be able to reference them during linkage (thanks to @michael-petch for pointing me to this option):

    -R filename
    --just-symbols=filename
      Read symbol names and their addresses from filename, but do not relocate it
      or include it in the output.
    

    Concretely, using -r to create intermediate linker files, one can use:

    ld -r --just-symbols=bootloader.elf -o bootloader-interface.elf \
      --retain-symbols-file to-export.txt
    

    to create an intermediate elf-file bootloader-interface.elf, that only contains the symbols listed in to-export.txt and does not contain any contents for the symbols, and then use that elf-file just like any other source during linkage.

    In a linker script this file can be brought into the linkage with:

    INPUT(path/to/bootloader-interface.elf);
    

    Then all exported symbols can be used inside the linker script for application.elf and also consequently referenced from the object files for application.