Serious C55x linker problem
1 Problem
At the end of the generated assembly for a function, the last instruction is a RET instruction with the opcode 0x48 0x04. If that RET instruction doesn’t end on a 32-bit boundary, an uninitialized hole gets created between the end of the RET instruction and the start of the next 32-bit boundary. In the case below, xx xx represents two bytes left as a hole:
0x10bc: 48 04 xx xx
Depending on what happens to be in the hole (random startup data in the DSP’s internal memory), the data in the hole can look like an instruction that should be executed in parallel with the RET instruction. In those cases, when the DSP executes RET (in parallel with the garbage), it tends to run off into the weeds. Eg. when the random data is 3b 8b:
0x10b8: 48 04 3b 8b RET || POP AR0,AR3
it jump off into the weeds at the RET instruction.
Other random values do not affect the RET instruction. E.g.:
0x10b8: 48 04 03 24 RET || RETCC T0 < #0
2 Solution
Add align(32) fill = 20h instructions to all text sections in linker command file:
.text > SDRAMTEXT align(32) fill = 20h /* Code */
.nettextfast > SDRAMTEXT align(32) fill = 20h
.nettextslow > SDRAMTEXT align(32) fill = 20h
.cprintfsect > SDRAMTEXT align(32) fill = 20h /* CPrintf support */
.commonsect > SDRAMTEXT align(32) fill = 20h /* common functions */