Hello,
so we have a bit more complex project. We are first creating relocatable output-modules, those are then linked in the final linking with a load-address and a run-address both inside a union. So the idea is to decide at runime which .text and .data to load from an external RAM into the internal SRAM of the Sitara. For pre-main-const-init I placed all .rodata in sections that have the same run and load-address, Becaus I am not sure about what the compiler will do with the rodata of the relocatable output modules.
The relocatable output modules have a lot of hidden symbols (when linking: -Wl,--hide=* and -Wl,--unhide= for symbols to make available to the outside) since both define the same symbols a lot. They also have a lot of references which are not compiled in. Since they use freeRTOS-functions and drivers of the AM243X-SDK. They are also linked in in the final linking.
When partial-linking I also needed to define separate sections for the output-modules since I couldn't find any other was to reference to the already linked-in libs:
SECTIONS { .textFastLibs: { -l "lib1fastlib"(.text) } .rodataFastLibs: { -l "lib1fastlib"(.rodata) } }
and the same thing for a lib2.
So I placed them inside the linker like this (names changed due to sensitive information):
UNION { .lib1Code: { -l "lib1usinglib.a"(.text), -l "lib1.out"(.text), } load > MCU1_0_PSRAM_CODE, palign(8), table(LIB1_CODE) .lib2Code: { -l "lib2usinglib.a"(.text), -l "lib2.out"(.text) } load > MCU1_0_PSRAM_CODE, palign(8), table(LIB2_CODE) } run > MCU1_0_R5F_MEM_TEXT
the same for the .data:
UNION { .eipData: { -l "lib1usinglib.a"(.data), -l "lib1.out"(.data), -l "lib1.out"(.bss) } load > MCU1_0_PSRAM_DATA, palign(8), table(LIB1_DATA) .pntData: { -l "lib2usinglib.a"(.data), -l "lib2.out"(.data), -l "lib2.out"(.bss) } load > MCU1_0_PSRAM_DATA, palign(8), table(LIB2_DATA) } run > MCU1_0_SPACE
and the fast-libs shall reside in TCM:
UNION { .fastTextLib1: { -l "lib1.out"(.textFastLibs) } load > MCU1_0_PSRAM_CODE, palign(8), table(LIB1_FAST_CODE) .fastTextLib2: { -l "lib2.out"(.textFastLibs) } load > MCU1_0_PSRAM_CODE, palign(8), table(LIB2_FAST_CODE) } run > R5F_TCMA
Also the .rodata-sections are placed in SRAM independently, so with unique load- and run-addresses each that the const-init does not get confused.
In my understanding now all relevant sections of the relocatable output-module should be defined and set correctly.
The map-file shows me this:
SEGMENT ALLOCATION MAP run origin load origin length init length attrs members ---------- ----------- ---------- ----------- ----- ------- 00000000 00000000 00000048 00000048 r-x 00000000 00000000 00000040 00000040 r-x .vectors 00000040 00000040 00000008 00000008 r-- .ARM.exidx 00000100 500e0150 00001e40 00001e40 r-x 00000100 500e0150 00001e40 00001e40 r-x .fastTextLib1 00000100 500dddc0 00002390 00002390 r-x 00000100 500dddc0 00002390 00002390 r-x .fastTextLib2 00002490 00002490 000016a0 000016a0 r-x 00002490 00002490 00000c40 00000c40 r-x .text.hwi 000030d0 000030d0 00000490 00000490 r-x .text.cache 00003560 00003560 000002e0 000002e0 r-x .text.mpu 00003840 00003840 00000110 00000110 r-x .text.atexit_register 00003950 00003950 000000b8 000000b8 r-x .text.__cxa_finalize 00003a08 00003a08 00000098 00000098 r-x .text._outs 00003aa0 00003aa0 00000050 00000050 r-x .text._outc 00003af0 00003af0 00000020 00000020 r-x .text.__cxa_atexit 00003b10 00003b10 00000010 00000010 r-x .text.__aeabi_errno_addr 00003b20 00003b20 00000008 00000008 r-x .text.__cxa_ia64_exit 00003b28 00003b28 00000008 00000008 r-x .text._nop 00003b30 00003b30 00000800 00000000 rw- 00003b30 00003b30 00000800 00000000 rw- .sysmem 41010000 41010000 00003300 00003300 r-- 41010000 41010000 00000100 00000100 r-- .irqstack 41010100 41010100 00001000 00001000 r-- .fiqstack 41011100 41011100 00002000 00002000 r-- .svcstack 41013100 41013100 00000100 00000100 r-- .abortstack 41013200 41013200 00000100 00000100 r-- .undefinedstack 50000000 50000000 0007a840 0007a840 r-x 50000000 50000000 0006af90 0006af90 r-x .textStack 5006af90 5006af90 0000f8b0 0000f8b0 r-- .rodataStack 50334840 50334840 0000bc20 0000bc20 rw- 50334840 50334840 0000bc20 0000bc20 rw- .dataStack 70080000 70080000 00041878 00041878 rw- 70080000 70080000 00010000 00010000 rw- .stack 70090000 70090000 0002fa78 0002fa78 rw- .bss 700bfa78 700bfa78 00001e00 00001e00 rw- .data 700c1880 5031e240 00016600 00016600 rw- 700c1880 5031e240 00016600 00016600 rw- .lib1Data 700c1880 50300000 0001e240 0001e240 rw- 700c1880 50300000 0001e240 0001e240 rw- .lib2Data 700f0000 700f0000 00000018 00000018 r-- 700f0000 700f0000 00000018 00000018 r-- .init_array 700f0020 700f0020 000669d8 000669d8 r-x 700f0020 700f0020 000002c0 000002c0 r-x .text.boot 700f02e0 700f02e0 00048810 00048810 r-x .text 70138af0 70138af0 0000f8c0 0000f8c0 r-- .rodata 701483b0 701483b0 00001170 00001170 r-- .rodataLib1 70149520 70149520 00005980 00005980 r-- .rodataLib2 7014eea0 7014eea0 00003600 00003600 r-- .rodataFastLib1 701524a0 701524a0 00004558 00004558 r-- .rodataFastLib2 70156a00 500bb0d0 00022cf0 00022cf0 r-x 70156a00 500bb0d0 00022cf0 00022cf0 r-x .lib1Code 70156a00 5007a840 00040890 00040890 r-x 70156a00 5007a840 00040890 00040890 r-x .lib2Code 70197290 70197290 00000060 00000060 r-- 70197290 70197290 00000060 00000060 r-- .ovly
But now I can't proceed over __TI_auto_init_nobinit. It runs into an undefined-handler. I display two scenarios:
1. trampolines
So I checked the map-file again.
And there I found this in the FAR CALL TRAMPOLINES-section of the map-file (first value is the callee address, second trampolin address, third call-address):
the containing lib was placed explicitly in PSRAM (GPMC so the 0x5.... addresses) inside a section:
But if you look at the map-file where the SEGMENT ALLOCATION MAP is shown you see that this section explicitly is used for the lib1Code and lib2Code-run-address.
So it's not even a thing about the lib1 oder lib2 weren't loaded correctly it happens way before we come to this point, so even before we reach main().
Why is there a callee of a trampolin generated in the middle of the run-address-section? I also checked the memory view:
The register-view of CCS doesn't really help.
Additionally I made a core trace to catch this better:
columns are RowNo, PC, OpCode, Function, Line No, File, Directory, Cycles, Status ("undefined instruction" is the last status). Interestingle the calls before this call don't make any sense because somehow some functions are already called that should be called later on but not before main.
How can I prevent the Linker from doing such things? Or am I the one doing a mistake here?
I guess it's important to notice the lib which uses this trampoline is in no way connected to the libs which are running at this section later on. Also it's not the only callee-address which is located there but probably the first one which gets called and produces this undefined abort.
2. static global
So I tried removing the part where at least the CCS crashed (the corresponding object is not created) And now it crashes at another part which is not inside the run-section:
the map-file changed to the following:
SEGMENT ALLOCATION MAP run origin load origin length init length attrs members ---------- ----------- ---------- ----------- ----- ------- 00000000 00000000 00000048 00000048 r-x 00000000 00000000 00000040 00000040 r-x .vectors 00000040 00000040 00000008 00000008 r-- .ARM.exidx 00000100 500de950 00001e40 00001e40 r-x 00000100 500de950 00001e40 00001e40 r-x .fastTextLib1 00000100 500dc5c0 00002390 00002390 r-x 00000100 500dc5c0 00002390 00002390 r-x .fastTextLib2 00002490 00002490 000016a0 000016a0 r-x 00002490 00002490 00000c40 00000c40 r-x .text.hwi 000030d0 000030d0 00000490 00000490 r-x .text.cache 00003560 00003560 000002e0 000002e0 r-x .text.mpu 00003840 00003840 00000110 00000110 r-x .text.atexit_register 00003950 00003950 000000b8 000000b8 r-x .text.__cxa_finalize 00003a08 00003a08 00000098 00000098 r-x .text._outs 00003aa0 00003aa0 00000050 00000050 r-x .text._outc 00003af0 00003af0 00000020 00000020 r-x .text.__cxa_atexit 00003b10 00003b10 00000010 00000010 r-x .text.__aeabi_errno_addr 00003b20 00003b20 00000008 00000008 r-x .text.__cxa_ia64_exit 00003b28 00003b28 00000008 00000008 r-x .text._nop 00003b30 00003b30 00000800 00000000 rw- 00003b30 00003b30 00000800 00000000 rw- .sysmem 41010000 41010000 00003300 00003300 r-- 41010000 41010000 00000100 00000100 r-- .irqstack 41010100 41010100 00001000 00001000 r-- .fiqstack 41011100 41011100 00002000 00002000 r-- .svcstack 41013100 41013100 00000100 00000100 r-- .abortstack 41013200 41013200 00000100 00000100 r-- .undefinedstack 50000000 50000000 00079038 00079038 r-x 50000000 50000000 00069790 00069790 r-x .textStack 50069790 50069790 0000f8a8 0000f8a8 r-- .rodataStack 50334840 50334840 0000bc20 0000bc20 rw- 50334840 50334840 0000bc20 0000bc20 rw- .dataStack 70080000 70080000 00041860 00041860 rw- 70080000 70080000 00010000 00010000 rw- .stack 70090000 70090000 0002fa78 0002fa78 rw- .bss 700bfa78 700bfa78 00001de8 00001de8 rw- .data 700c1860 5031e240 00016600 00016600 rw- 700c1860 5031e240 00016600 00016600 rw- .eipData 700c1860 50300000 0001e240 0001e240 rw- 700c1860 50300000 0001e240 0001e240 rw- .pntData 700f0000 700f0000 00000018 00000018 r-- 700f0000 700f0000 00000018 00000018 r-- .init_array 700f0020 700f0020 000662a8 000662a8 r-x 700f0020 700f0020 000002c0 000002c0 r-x .text.boot 700f02e0 700f02e0 00048570 00048570 r-x .text 70138850 70138850 0000f430 0000f430 r-- .rodata 70147c80 70147c80 00001170 00001170 r-- .rodataLib1 70148df0 70148df0 00005980 00005980 r-- .rodataLib2 7014e770 7014e770 00003600 00003600 r-- .rodataFastLib1 70151d70 70151d70 00004558 00004558 r-- .rodataFastLib2 701562d0 500b98d0 00022cf0 00022cf0 r-x 701562d0 500b98d0 00022cf0 00022cf0 r-x .lib1Code 701562d0 50079040 00040890 00040890 r-x 701562d0 50079040 00040890 00040890 r-x .lib2Code 70196b60 70196b60 00000060 00000060 r-- 70196b60 70196b60 00000060 00000060 r-- .ovly
and the address is now in the .data-section:
The core-trace is now really weird:
Could it be that at some earlier point the software starts to take the wrong way somehow? But the question would be: why?
I wanted to disassembly-debug the whole process but as soon as I get into the first branches inside __TI_auto_init_nobinit and in the __cxx_global_var_init which are opening the corresponding files in the view, CCS constantly crashes all the time. So it's impossible to debug this problem.
Compile-options we use:
"-Wno-gnu-variable-sized-type-not-at-end"
"-mcpu=cortex-r5"
"-mfloat-abi=hard"
"-mfpu=vfpv3-d16"
"-Wno-error=ti-macros"
"-Wno-unused-function"
"-Wno-invalid-command-line-argument"
"-fno-rtti"
"-ffunction-sections"
"-fdata-sections"
"-mno-unaligned-access"
Additional link-options we use:
"-Wl,--reread_libs"
"-Wl,--ram_model"
"-Wl,--diag_suppress=10063"
"-Wl,-e_vectors"
Best regards
Felix