1

How to put functions from one object file to one special section and memory region for GCC linker? I am building one standalone application for Xilinx MPSoC A53 processor. GNU ld from Linaro 2.27 is used. Xilinx software is Xilinx SDK 2017.4. I plan to put most code into DDR and some critical functions from one file into on-chip memory. I checked '4.6.4.5. Input Section Example' from Using_ld_the_GNU_Linker/sections.html. So I created the following linker script. The output section '.text_ocm' is added by me.

.text_ocm : {
    src/ocm_init.o(.text)
}  > psu_ocm_ram_0_MEM_0

.text : {
   KEEP (*(.vectors))
   *(.boot)
   *(.text)
   *(.text.*)
   *(.gnu.linkonce.t.*)
   *(.plt)
   *(.gnu_warning)
   *(.gcc_execpt_table)
   *(.glue_7)
   *(.glue_7t)
   *(.ARM.extab)
   *(.gnu.linkonce.armextab.*)
} > psu_ddr_0_MEM_0

But I got error message. It seems there are two 'ocm_init'. But there is only one definition for 'ocm_init' in file 'src/ocm_init.c' my source code.

'Invoking: ARM v8 gcc linker'
aarch64-none-elf-gcc -Wl,-T -Wl,../src/lscript.ld -L../../a53a0_ddrsr_wfi_bsp/psu_cortexa53_0/lib -o "a53a0_ddrsr_wfi_step4_from_ddr.elf"  ./src/ocm_init.o ./src/gic_setup.o ./src/helloworld.o ./src/platform.o ./src/timer.o   -Wl,--start-group,-lxil,-lgcc,-lc,--end-group -Wl,--start-group,-lxil,-lmetal,-lgcc,-lc,--end-group -Wl,--start-group,-lxilpm,-lxil,-lgcc,-lc,--end-group
./src/ocm_init.o: In function `ocm_init':
C:\prj\mpsoc\v174\zcu102\a53a0_ddr\Debug/../src/ocm_init.c:1667: multiple definition of `ocm_init'
src/ocm_init.o:C:\prj\mpsoc\v174\zcu102\a53a0_ddr\Debug/../src/ocm_init.c:1667: first defined here
Hank Fu
  • 43
  • 5
  • 1
    I assume that since you're explicitly calling out src/ocm_init.o(.text) to a special section, that you'll have to exclude that same file from the .text section *(.text), otherwise you're asking the linker to include it twice... – Ross Mar 13 '18 at 13:09
  • I tried the following two method to exclude ocm_init.o. But they both do not work. I got same error. .text : { KEEP (*(EXCLUDE_FILE (src/ocm_init.o) .vectors)) *(EXCLUDE_FILE (src/ocm_init.o) .text) *(EXCLUDE_FILE (src/ocm_init.o) .text.*) .........) } > psu_ddr_0_MEM_0 .text : { KEEP (*(EXCLUDE_FILE (*ocm_init.o) .vectors)) *(EXCLUDE_FILE (*ocm_init.o) .text) *(EXCLUDE_FILE (*ocm_init.o) .text.*) ........ ) } > psu_ddr_0_MEM_0 – Hank Fu Mar 14 '18 at 02:03
  • As an alternative to telling the linker to include a whole object file in one section, you should also be able to just define a section and then go to the individual functions in that .c file, drown them in some non-standard gcc goo syntax (which I don't remember, lots of __attribute and __declspec no doubt) and let the linker take it from there. – Lundin Mar 14 '18 at 09:55

1 Answers1

1

The linker cares about the leading ./ in some ways when matching file names, so either write

.text_ocm : {
    *src/ocm_init.o(.text)
}  > psu_ocm_ram_0_MEM_0

in your linker script, or reference the object file as src/ocm_init.o on your linker command line.

(It's not really intuitive why this omission causes multiple definitions, but I could reproduce your problem, and the change fixes it.)

matli
  • 27,922
  • 6
  • 37
  • 37