This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM46 .init_array section with linker generated CRC issue

Other Parts Discussed in Thread: HALCOGEN

I am trying to use the RM46 CRC module to calculate and verify CRC's for the linker generated CRC table. The problem that I am having is that the HalCoGen generaed crc driver (crc.h / crc.c) uses 64-bit words to generate the CRC (reference crcSignGen within crc.c).

If I try to apply a palign=8 to the .init_array section so it is 64-bit aligned and the size is aligned to 64-bits, the initialization for the global constructor has an issue since it uses the size of the .init_array section to call the list of constructors. The problem is that the palign=8 can pad the end of the .init_array with zeros or a defined fill, causing the run_pinit in the C++ startup to fail or try to run the addresses generated by the padding.

Any one run in to this same issue?

Link command file contains:

SECTIONS
{
.intvecs : {}  align=8, crc_table(_vcmCrcTable, algorithm=TMS570_CRC64_ISO) > VECTORS
.text : {} align=8, crc_table(_vcmCrcTable, algorithm=TMS570_CRC64_ISO) > FLASH0
.const : {} align=8, crc_table(_vcmCrcTable, algorithm=TMS570_CRC64_ISO) > FLASH0
.cinit : {} align=8, crc_table(_vcmCrcTable, algorithm=TMS570_CRC64_ISO) > FLASH0
.init_array : {} align=8, crc_table(_vcmCrcTable, algorithm=TMS570_CRC64_ISO) > FLASH0
.TI.crctab {} > FLASH1

.bss : {} > RAM
.data : {} > RAM
.sysmem : {} > RAM
}

If the .init_array section is not aligned to 64-bit and the size is on a 64-bit boundary, that causes a problem with using the CRC module and DMA (64-bit transfers). If I force the alignment and size with the palign=8, the linker will pad zeros at the end of the .init_array section, thus causing problems with the run_pinit when it tries to use the section size to call all constructors (i.e. padded area causes the run_pinit to execute at address zero).

Here is run_init from the ti-cgt-arm_5.2.4/lib/src autoinit.h :

#pragma FUNC_ALWAYS_INLINE(run_pinit)
static __inline void run_pinit(void)
{
#ifdef __TI_EABI__
/*------------------------------------------------------------------------*/
/* Process Pinit table for ELF. */
/* The section is not NULL terminated, but can be accessed by pointers */
/* which point to the beginning and end of the section. */
/*------------------------------------------------------------------------*/
if (PINIT_BASE != PINIT_LIMIT)
{
int i = 0;
while (&(PINIT_BASE[i]) != PINIT_LIMIT)
PINIT_BASE[i++]();
}
#else
...

This initialization does not validate each of the constructor pointer in the table to be non-null prior to using?

Any help here would be greatly appreciated.

Thanks,
Don ...

  • Don,

    will check on this and get back to you.
  • Hi Don,

    I think I saw a similar issue on the .cinit section which is for initializing global variables, but I never debugged the problem as it disappeared as soons as I disabled the cinit compression in the linker: --cinit_compression=off

    The section .init_array contains global C++ constructors. I'm just curious, are you using C++?

    Best Regards,
    Christian
  • Hi Don,

    I think I know what causes the issue in case you don't use palign.

    1. Your Section (.init_array) doesn't end on a 8-byte boundary
    2. The CRC algorithm assumes that the last (incomplete) 8-byte word is padded with all '0'
    3. In your case some data but not all '0' are following immediately
    4. This will cause the CRC verification to fail

    You could possibly fix this with the following GROUP directive in the Linker Command File:

    GROUP :
    {
        .init_array : {} align=8, crc_table(_my_crc_table, algorithm=TMS570_CRC64_ISO)
        .dummy : {. += 7;} fill=0x00000000
    } > FLASH0 | FLASH1

    • The align=8 will ensure the proper alignment of the start address.
    • The .dummy section will add a all '0' padding to the .init_array section

    With this it is always ensured that the .init_section will be padded with all '0' and the size of the .init_section isn't changed as it would be by using the palign.

    I hope this helps!

    Best Regards,
    Christian

    Note: You have to ensure, that the data size in the CRC table is always round up to the next 8-byte boundary.
    You can do this with the following code: sCrcModConfig.data_length  = (_my_crc_table.recs[i].size + 7ul) / 8ul; /* Amount of in 8-byte words */

  • Don,

    Did this solve the issue ? pls let us know so that we can close this thread accordingly.