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.

Is it correct for TI ARM Clang v1.3.0 to place .init_array in a read/write section?

Other Parts Discussed in Thread: MSP432E401Y

When attempting to use TI Clang v1.3.0-beta.1 to create a C++ example for a MSP430E301Y the program was failing to reach main, with the __TI_decompress_lzss() function suffering a hard fault when it attempted to write to flash.

The problem is that the .init_array section has been placed in a read/write section by the linker. As shown in the linker map file:

SEGMENT ALLOCATION MAP

run origin  load origin   length   init length attrs members
----------  ----------- ---------- ----------- ----- -------
00000000    00000000    0002d44b   0002d44b    r-x
  00000000    00000000    00000208   00000208    r-- .intvecs
  00000208    00000208    0002a9c2   0002a9c2    r-x .text
  0002abd0    0002abd0    0000287b   0000287b    r-- .rodata
0002d44c    0002d44c    00000008   00000000    rw-
  0002d44c    0002d44c    00000008   00000000    rw- .init_array

LINKER GENERATED COPY TABLES

__TI_cinit_table @ 0002d4f8 records: 3, size/record: 8, table size: 24
	.data: load addr=0002d458, load size=0000007b bytes, run addr=20031000, run size=00000e45 bytes, compression=lzss
	.init_array: load addr=0002d4d3, load size=0000000d bytes, run addr=0002d44c, run size=00000008 bytes, compression=lzss
	.bss: load addr=0002d4f0, load size=00000008 bytes, run addr=20031e48, run size=00000478 bytes, compression=zero_init

The linker command file was placing the .init_array section in flash (ROM) which matches the example given in 3.1. Source Files of the tiarmclang Getting Started Guide:

    .init_array : > FLASH

The example is attached.

If the same example is used with the TI ARM v20.2.5 compiler then the .init_array section created by the linker is read-only, and thus can be placed in flash.

Is it a bug that the TI ARM Clang v1.3.0 linker creates the .init_array section as read/write, rather than read-only?

MSP432E401Y_TI_CLANG.zip

  • Hi Chester,

    Let me run this by our tools group.

  • Hi Chester,

    The example in the tiarmclang user guide that you refer to uses an example linker command file:

    /****************************************************************************/
    /* Example Linker Command File                                              */
    /****************************************************************************/
    -c                                         /* LINK USING C CONVENTIONS      */
    -stack  0x8000                             /* SOFTWARE STACK SIZE           */
    -heap   0x2000                             /* HEAP AREA SIZE                */
    --args  0x1000
    
    /* SPECIFY THE SYSTEM MEMORY MAP */
    
    MEMORY
    {
        P_MEM    : org = 0x00000020   len = 0x20000000  /* PROGRAM MEMORY (ROM) */
        D_MEM    : org = 0x20000020   len = 0x20000000  /* DATA MEMORY    (RAM) */
    }
    
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
    
    SECTIONS
    {
        .intvecs    : {} > 0x0             /* INTERRUPT VECTORS                 */
        .bss        : {} > D_MEM           /* GLOBAL & STATIC VARS              */
        .data       : {} > D_MEM
        .sysmem     : {} > D_MEM           /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack      : {} > D_MEM           /* SOFTWARE SYSTEM STACK             */
    
        .text       : {} > P_MEM           /* CODE                              */
        .cinit      : {} > P_MEM           /* INITIALIZATION TABLES             */
        .const      : {} > P_MEM           /* CONSTANT DATA                     */
        .rodata     : {} > P_MEM
        .ARM.exidx  : {} > P_MEM
        .init_array : {} > P_MEM           /* C++ CONSTRUCTOR TABLES            */
    }

    this is not intended to model memory on any particular device. I run that example on an internal standalone simulator. Perhaps this could be made clearer in the user guide text.

    With that said, I find it strange that the linker does cinit compression on the .init_array section since it is only 8 bytes long. I will look into that.

    Are you able to run a simple hello world program using a linker command file that models the memory layout of the MSP432 device?

    ~ Todd

  • With that said, I find it strange that the linker does cinit compression on the .init_array section since it is only 8 bytes long

    I agree that looks strange, and appears to be the reason why the .init_array section gets created as read/write. The compressed "load size" is 13 bytes and the un-compressed "run size" is 8 bytes, and so the compression isn't actually saving any space.

    Are you able to run a simple hello world program using a linker command file that models the memory layout of the MSP432 device?

    Looking at a CCS 10.3.0.00007 it is only the following device files which contain setup information for TICLANG:

    $ find ~/ti/ccs1030/ccs/ccs_base/ -name '*.xml' -print0 | xargs -0 -n100 grep -l TICLANG
    /home/mr_halfword/ti/ccs1030/ccs/ccs_base/common/targetdb/devices/msp432e411y.xml
    /home/mr_halfword/ti/ccs1030/ccs/ccs_base/common/targetdb/devices/msp432e401y.xml

    The C++ hello world attached in the first post was created for a MSP432E401Y as that is one of the devices in CCS 10.3 which had support to TICLANG when creating a new project, and the msp432e401y.cmd copied into the project at creation placed .init_array in FLASH.

    If the msp432e401y.cmd is changed to place .init_array in SRAM then the program runs.

  • Hi Chester,

    I have filed a defect report against the TI Arm Clang linker for the inefficiency issue. The external link for this defect report is: https://sir.ext.ti.com/jira/browse/EXT_EP-10348 

    The .init_array section should be interpreted as read-only from a programming perspective. If there is a legitimate reason why the linker must generate a cinit entry for the .init_array section, then it needs to be placed in read-write target memory for a linker command file that is modelling the memory of a hardware device.

    If the outcome of the cinit inefficiency issue is that the .init_array can be directly initialized (without the need for a cinit record), then it will be safe to place the .init_array section in target ROM.

    ~ Todd