For EABI cinit copy "compression", the linker incorrectly sets the number of bytes to copy for smaller copy initialization sizes

XMLWordPrintable

    • Type: Bug
    • Resolution: Fixed
    • Priority: Medium
    • Code Generation Tools
    • CODEGEN-10306
    • Show
      https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1190185/cl2000-linker-generating-wrong-autoinitialization-data/4484946?tisearch=e2e-sitesearch&keymatch=EXT_EP-10875#4484946
    • Hide
      C29_1.0.0.LTS
      C2000_16.9.0.LTS
      ARMCLANG_2.1.0.LTS
      C7000_2.1.0.LTS
      MSP430_21.6.0.LTS
      C7000_3.1.0.LTS
      C7000_4.1.0.LTS
      C7000_1.4.0.LTS
      ARMCLANG_1.3.0.LTS
      MSP430_16.9.0.LTS
      C6000_8.2.0
      C2000_18.1.0.LTS
      C6000_8.3.0
      MSP430_20.2.0.LTS
      ARM_18.12.0.LTS
      ARMCLANG_4.0.0.LTS
      C7000_5.0.0.LTS
      C2000_21.6.0.LTS
      ARM_20.2.0.LTS
      C7000_4.0.0.STS
      C2000_20.2.0.LTS
      ARM_18.1.0.LTS
      MSP430_18.1.0.LTS
      ARM_16.9.0.LTS
      C2000_22.6.0.LTS
      ARMCLANG_3.2.0.LTS
      MSP430_18.12.0.LTS
      C2000_18.12.0.LTS
      Show
      C29_1.0.0.LTS C2000_16.9.0.LTS ARMCLANG_2.1.0.LTS C7000_2.1.0.LTS MSP430_21.6.0.LTS C7000_3.1.0.LTS C7000_4.1.0.LTS C7000_1.4.0.LTS ARMCLANG_1.3.0.LTS MSP430_16.9.0.LTS C6000_8.2.0 C2000_18.1.0.LTS C6000_8.3.0 MSP430_20.2.0.LTS ARM_18.12.0.LTS ARMCLANG_4.0.0.LTS C7000_5.0.0.LTS C2000_21.6.0.LTS ARM_20.2.0.LTS C7000_4.0.0.STS C2000_20.2.0.LTS ARM_18.1.0.LTS MSP430_18.1.0.LTS ARM_16.9.0.LTS C2000_22.6.0.LTS ARMCLANG_3.2.0.LTS MSP430_18.12.0.LTS C2000_18.12.0.LTS
    • Hide
      C2000_25.3.0.LTS*
      MSP430_21.6.2.LTS*
      C29_1.0.1.LTS*
      C7000_4.1.2.LTS*
      C2000_22.6.3.LTS*
      C7000_6.0.0.LTS*
      C2000_21.6.2.LTS*
      C7000_5.0.1.LTS*
      MSP430_20.2.8.LTS*
      ARMCLANG_4.0.3.LTS*
      C6000_8.3.14
      ARMCLANG_3.3.0.LTS*
      Show
      C2000_25.3.0.LTS* MSP430_21.6.2.LTS* C29_1.0.1.LTS* C7000_4.1.2.LTS* C2000_22.6.3.LTS* C7000_6.0.0.LTS* C2000_21.6.2.LTS* C7000_5.0.1.LTS* MSP430_20.2.8.LTS* ARMCLANG_4.0.3.LTS* C6000_8.3.14 ARMCLANG_3.3.0.LTS*
    • default
    • Hide
      Avoid using copy "compression" by setting --cinit_compression=rle,lzss
      However, confirm compression used in map file by reviewing cinit table

      NOTE: below option disables rle/lzss compressions and will result in only copy
      compressions being used:
         --cinit_compression=off

      If copy compression cannot be avoided then manually update impacted variabled
      at the start of main().
      Show
      Avoid using copy "compression" by setting --cinit_compression=rle,lzss However, confirm compression used in map file by reviewing cinit table NOTE: below option disables rle/lzss compressions and will result in only copy compressions being used:    --cinit_compression=off If copy compression cannot be avoided then manually update impacted variabled at the start of main().

      EABI cinit copy "compression" involves no actual compression. Instead the
      cinit records include the actual data to be copied out during initialization
      as well as the size of the data to be copied.

      For small size initializations, the linker was incorrectly setting the number
      of bytes to copy. This would result in a cinit record that could write over an adjacent initialized variable in memory during cinit.

      Here's an example where var_copy_issue's cinit record will be generated with
      incorrect size which then over writes the initialization of var_impacted:
      main.c

      #include <stdio.h>
      __attribute__((location(0xC001))) char var_copy_issue = 0xABCD;
      __attribute__((location(0xC002))) long var_impacted = 0XABCD1234;
      __attribute__((location(0xC004))) long long var_no_issue = 0xABCD1234BEEF5678;
      int main(void) {
          volatile long long s = var_copy_issue + var_impacted + var_no_issue;
          printf("var_copy_issue  0x%04x \n", var_copy_issue);
          printf("var_impacted    0x%lx  \n", var_impacted);
          printf("var_no_issue    0x%llx \n", var_no_issue);
          return 0;
      }
      
      

      Compile above with below that forces copy "compression":
      cl2000 -v28 --float_support=fpu32 --abi=eabi main.c -z -llnk.cmd --cinit_compression=off

      Running above generates this output:

         var_copy_issue  0xabcd 
         var_impacted    0xabcd0000   <-- should be 0xabcd1234
         var_no_issue    0xabcd1234beef5678 
      

      Linker map file shows below entry for var_copy_issue with compression=copy and
      run_size=1 which looks correct:

      __TI_cinit_table @ 00081eba records: 5, size/record: 4, table size: 20
      	.TI.bound:var_no_issue: load addr=00081e9e, load size=00000008 bytes, run addr=0000c004, run size=00000004 bytes, compression=copy
      	.TI.bound:var_impacted: load addr=00081ea6, load size=00000006 bytes, run addr=0000c002, run size=00000002 bytes, compression=copy
      	.TI.bound:var_copy_issue: load addr=00081eac, load size=00000005 bytes, run addr=0000c001, run size=00000001 bytes, compression=copy
      

      However, dissassembling above executable and viewing var_copy_issue's cinit
      record shows the bug with incorrect run_size set to 2:

      00081ea6   0000    .word 0x0000   cinit handler index
      00081ea7   0000    .word 0x0000   padding to align below run_size
      00081ea8   0002    .word 0x0002   32bit run_size=2 but should instead be 1
      00081ea9   0000    .word 0x0000
      00081eaa   1234    .word 0x1234   var_copy_issue's initialization value
      00081eab   abcd    .word 0xabcd   padding to align next cinit record
      

      More details per ISA target:
      Below table shows the cases with the issue.
      NOTE: some targets have 8bit bytes and some have 16bit bytes. Both are
      affected.
      The second column indicates the size of variable(s) that could cause the issue.
      The third column shows the copy-record size that was incorrectly being used to set the copy-size.

                             var bytes         handler_index+padding
            TIARMCLANG/ARM   1-3 8bit bytes      4 bytes
            MSP              1   8bit byte       2 bytes
            C29              1-3 8bit byte       4 bytes
            C60              1-3 8bit byte       4 bytes
            C70              1-7 8bit byte       8 bytes this is worst impacted
            C28              1   16bit "byte"    2 16bit "bytes"
      

      The bug could occur for cases where the number of bytes of variable(s) to
      copy-initialize is less than above column 3's entry for a copy-record's
      handler_index+padding.

      Additionally, for the bug to occur, there needs to be a variable in memory
      located directly after above variable with the cinit issue. And the sequence
      of cinit initializations needs to initialize var_impacted first followed by
      initialization of var_copy_issue (which then overwrites the earlier
      initialization).

      The other way this issue could occur is if a cinit record size to copy
      was set smaller than the variable size. This would result in a variable
      not having the full initialization performed.

            Assignee:
            TI User
            Reporter:
            TI User
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved:

                Connection: Intermediate to External PROD System
                EXTSYNC-3471 - For EABI cinit copy "compression", ...
                SYNCHRONIZED
                • Last Sync Date: