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.

Linker splits .text section and creates NOP trampoline func on section border

Hello all,


I recently run into an issue where the compiler obviously creates an invalid executable.


We are using a DM6435 with CCS 5.2.0, SYS/BIOS 6.34.2.18, XDC 3.24.3.33 and NDK 2.21.0.32. Both usign C6000 CGTools 7.3.4 and 7.4.14 we see the following problem:


Our output file is quite large (approx. 9 MB) and the .text section is sometimes automatically splitted into 2 (sometimes even more) sections. The resulting .text.1 section is quite large, the subsequent .text.2 section usually contains only a few functions, probably only some trampoline functions.


The resulting MAP files usually look like that (some lib and func names replaced since I don't want to see these names in public):

MEMORY CONFIGURATION

         name            origin    length      used     unused   attr    fill
----------------------  --------  ---------  --------  --------  ----  --------
...
  DDR2                  80000000   01000000  00926c7a  006d9386  RWIX
  DDR2_UNINITIALIZED    81000000   00400000  0030649b  000f9b65  RWIX
  DDR2_HEAP             81400000   0ac00000  0ac00000  00000000  RWIX
  DDR2_STATIC           8c000000   04000000  00000000  04000000  RWIX

...

.text.1    0    80000040    0082e2a0     
                  80000040    000163e0     lib_a.lib : obj_1.obj (.text)
                  80016420    000152e0     lib_b.lib : obj_2.obj (.text)
...
                  8082e2a0    00000020     lib_c.lib : obj_3.o ($Tramp$S$$_Func1)
                  8082e2c0    00000020     lib_d.lib : obj_4.o ($Tramp$S$$_Func2)

.text.2    0    8082e2c0    00000200     
                  8082e2c0    00000020     lib_d.lib : obj_4.o ($Tramp$S$$_Func2)
                  8082e2e0    00000020     lib_c.lib : obj_5.o ($Tramp$S$$_Func3)
                  8082e300    00000020               : obj_6.o ($Tramp$S$$_Func4)
...

In the resulting binary file the trampoline function listed both at the end of .text.1 and at the beginning of .text.2 contains only NOPs (0x00):

If the .text section is splitted into more than two parts the same thing happens to the (trampoline) functions placed at the beginning of the next .text.<n> sections too.

This problem will finally cause our application to crash since instead of calling Func2() (using the trampoline) a different Func3() will be called (because execution falls through into the next trampoline function for Func3() with invalid args since these were prepared for Func2()) and if it doesn't crash itself (because of the silly args) the result is not the expected result of Func2() which may finally cause the calling code to crash because of "unexpected behaviour of Func2()".

All program code and vars (.pinit, .text, .const, .cinit, .switch, .neardata, .rodata, .bss), all together approx. 9,4 MB are put into the 16 MB large "DDR2" area. So I think there should be no need to split the .text section.

The problem seems to occure "randomly", at least we don't understand the situations triggering that behaviour. When we change some code somewhere the problem occures and disappears.

Despite I've been chasing the problem for quite a time I just recently understood what happens. Since I didn't store the MAP files of previous builds I only can talk about a few tries. But in these few tries it was always a linker generated trampoline function that has been "NOPed out", but it were trampolines for different functions. The address of the boundary between .text.1 and .text.2 is also not constant.

Why is the .text section splitted at all?

Why is the effected func listed both at the end of .text.1 section and the beginning of .text.2 section?

Why is the code of the first func in .text.2 replaced by NOPs?

And most important: What can we do to overcome this problem???

Any help will be greatly appreciated.

Thanks,

Lars

  • Sorry, the screenshot of the resulting binary file in my previous post seems to have been lost. So here the info comes again as text:

    In the resulting binary file the trampoline function listed both at the end of .text.1 and at the beginning of .text.2 contains only NOPs (0x00):

    0x8082E280: 0FD7B62A 0FC00BEA 007C0362 00008000
    0x8082E290: 0FA2F02A 0FC0206A 007C0362 00008000
    0x8082E2A0: 053C54F7 0522302A 0540206A 00280362
    0x8082E2B0: 053C52E6 00006000 00000000 00000000
    0x8082E2C0: 00000000 00000000 00000000 00000000
    0x8082E2D0: 00000000 00000000 00000000 00000000
    0x8082E2E0: 053C54F7 056B702A 05401E6A 00280362
    0x8082E2F0: 053C52E6 00006000 00000000 00000000
    0x8082E300: 053C54F7 0515F02A 0540206A 00280362
    0x8082E310: 053C52E6 00006000 00000000 00000000

  • Just to give a current slightly different constellation:

    The MAP now contains:

    .text.1    0    80000040    00825b40
    ...
                      80825b50    00000010     lib_a.lib : obj_1.obj ($Tramp$S$$_Func1)
                      80825b60    00000010     nettool.a64P : config.o64P ($Tramp$S$$_CfgGetEntry)
                      80825b70    00000010     --HOLE-- [fill = 0]
    .text.2    0    80825b60    00000180    
                      80825b60    00000010     nettool.a64P : config.o64P ($Tramp$S$$_CfgGetEntry)
                      80825b70    00000010     stk.a64P : bind.o64P ($Tramp$S$$_BindFree)
                      80825b80    00000020     lib_b.lib : obj_2.o ($Tramp$S$$_Func2)
                      80825ba0    00000010     stk.a64P : bind.o64P ($Tramp$S$$_BindGetFirst)
    ...

    In the resulting binary file the range from 0x825B60 to 0x825B7F is filled with 0x00, thus destroying both the trampoline functions for CfgGetEntry() and BindFree().


    May be this may give some additional hint what's going on...

    Lars

  • This is almost certainly a problem with the linker.  Unfortunately, the only way to move this issue forward is for us to reproduce it ourselves.  The easiest path is for you to send us your CCS project.  I understand your reluctance to post that on the forum.  Are you willing to send it just to me?

    Thanks and regards,

    -George

  • Hi George,

    thanks for this suggestion. I'm afraid it will take me some time to create a project which will help you to reproduce this behaviour without revealing too much confidential information about our code. :-(

    Me be we can try to discuss two general things before trying something like this:

    1. Why is the .text section splitted? Can this behaviour be controlled somehow?

    2. We are going to change our output format from COFF (where we saw this behaviour) to EABI in the near future. Is there a reasonable chance that the linker won't show this bug when schanging the output format? In that case it may be an option for us to create a running version by trial and error until we can finally change output format.

    Thanks,
    Lars
  • Lars Beikirch said:
    Why is the .text section splitted?

    We don't know.  That's one of things we want to investigate.

    Lars Beikirch said:
    We are going to change our output format from COFF (where we saw this behaviour) to EABI in the near future. Is there a reasonable chance that the linker won't show this bug when schanging the output format?

    Changing object file formats means many things are different.  I cannot guarantee the problem goes away.  But I think it is worth the attempt.

    Thanks and regards,

    -George

  • Hello George,

    George Mock said:
    Lars Beikirch
    We are going to change our output format from COFF (where we saw this behaviour) to EABI in the near future. Is there a reasonable chance that the linker won't show this bug when schanging the output format?

    Changing object file formats means many things are different.  I cannot guarantee the problem goes away.  But I think it is worth the attempt.


    After changing to EABI output format we saw the same issue: The .text section has been splitted (sometimes even into several parts) and at least at one section border we saw the well known overlap in the func code placement:

    .text.1    0    80000040    0081fc80     
    ...
                      8081fca0    00000010     lib1_eabi.lib : obj1.obj ($Tramp$S$$func1)

                      8081fcb0    00000010     nettool.ae64P : config.o64P ($Tramp$S$$CfgGetEntry)

    .text.2    0    8081fcb0    000001f0     
                      8081fcb0    00000010     nettool.ae64P : config.o64P ($Tramp$S$$CfgGetEntry)
                      8081fcc0    00000010     stk.ae64P : bind.o64P ($Tramp$S$$BindIF2IPHost)
    ...

    and the according trampoline func has been replaced by NOPs (0x00) in the resulting binary.

    During the last days I was trying to generate a dummy project for you that may reproduce this problem. Generating a lot of code by a view lines of nested macros works in general, but seems to bring the compiler to it's limits - after hours of compiling it often gives up by Out Of Memory. I'll continue trying to get it work somehow. Anyway I still don't know if it can reproduce the problem of broken trampolines...


    Best regards,

    Lars

  • Hi,

    a colleague of mine found out more details:

    Despite obviously the linker raises the issue by generating overlapping sections it turns from bad to worse by the hex6x tool:

    Loading the *.out file by JTAG works fine. Only generating a *.bin file changes the trampoline function placed in the overlapping area to NOPs (0x00).

    hex6x generates a warning:

    Translating to Binary format...
      "Application.out"   ==> .startup
      "Application.out"   ==> .init_array
      "Application.out"   ==> .text.1
      "Application.out"   ==> .text.2
    warning: section Application.out(.text.2) at 08081fcb0h overlaps Application.out(.text.1)
      (Application.out(.text.2) incomplete or skipped)
      "Application.out"   ==> .const
      "Application.out"   ==> .switch
      "Application.out"   ==> .vecs
      "Application.out"   ==> .cinit

    (Unfortunately we didn't notice this warning so far since our project runs hex6x in an evironment swallowing the output. :-()


    My colleague found another thread dealing with a quite similar issue:

    e2e.ti.com/.../162185

    There was a statement the issue has been fixed in cgtools v7.3.6. Actually we see our problem using cgtools v7.3.4, v7.4.8 and v7.4.14, but it seems to disappear if we use cgtools v7.3.21. So I'm wondering if the issue actually has been fixed for the 7.3.x series 3 years ago, but not for even the brand new 7.4.x releases.


    Any statement?

     

    Best regards,

    Lars

  • Lars Beikirch said:
    Despite obviously the linker raises the issue by generating overlapping sections it turns from bad to worse by the hex6x tool:

    If the linker did its job properly, this would not occur.

    Lars Beikirch said:
    Loading the *.out file by JTAG works fine.

    I cannot explain that.  The sections are overlapping in .map file, and thus in the .out file.  So I don't understand how this can possibly work.

    Lars Beikirch said:
    My colleague found another thread dealing with a quite similar issue:

    That particular issue is fixed in the 7.4.x releases.  So while your issue is similar, we are confident it is different.

    I understand why you look for a solution that does not require you to send in a linker test case.  But I think it is unavoidable in this situation.  Remember that you can send the test case in only to me.

    A possible workaround to consider ...  I presume you have full control of the linker command file and can change it.  Avoid splitting the .text section.  The syntax looks like ...

        .text >> MR1 | MR2 | MR3

    See this brief explanation of section splitting.  The key is to change ">>" to ">".

    Thanks and regards,

    -George

  • Hello George,


    meanwhile we are not sure any more that 7.4.x versions actually raises the issue too. May be we saw it because the 7.4.x linker still used some object files generated by the 7.3.4 compiler. While trying to generate a test project for you I saw the problem dissapear several times when switching from compiler v7.3.4 to v7.4.8 or v7.4.14 by forcing a full recompile by deleting all *.obj files.


    So I'm still trying to generate something I could give you, but currently I'm not able to reproduce the problem using our current development state and v7.4.x CGTools. We will watch it in the next time for sure.


    Thanks for the advice how to control section splitting. My colleague found out himself that this seems to help meanwhile - despite it's not obvious since the section doesn't need to be splitted to fit into different memory areas.

    Best regards,
    Lars