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.

Compiler: CCS 5.1x, CGT 7.3.22: Automatically-created STI constructor asm changes slightly between builds.

Tool/software: TI C/C++ Compiler

I am trying to separate binary images using the hex6x tool (this is working already).  I'm in the nitty gritty details on what separates the 4 binaries I'm creating from the single *.out file. 

Question: I have a stub CPP file with two functions; funcA, funcB with some volatiles to keep them around;  The problem is when I change a different library input file with absolutely no "visible" ties to funcA/funcB, I still see unexplained changes in the disassembly for the automatically-generated constructor.

TEXT section .image4_text (Big Endian), 0xE0 bytes at 0xE0xx_xxxx. 

E0xx_x100:                  __sti___19__filename_cpp_fa5f8b8c:

...

...

...

b __cxa_guard_acquire.

...

b  __cxa_guard_release

mvk.L2 0,B4

mv.L1 A10, a4

mvk.S1 0x4064, a3        <<<<  This one changes.     In the previous build when I change code from a different input lib, the STI changes slightly.  The previous was 0x4024,A3 instead.

Any help appreciated.

Thanks!

Will

Processor: C6457

CCS 5.1x

CGT 7.3.22

  • I have a vague memory of something like this. But I was unable to find it in our bug database.  

    ixworks said:
    CGT 7.3.22

    This is a fairly old version of the compiler.  Is it practical for you to upgrade just for the purpose of testing?  I'd appreciate if you would try the latest compiler version (presently 8.2.2) to see if this has been fixed.  The article Compiler Releases has details on obtaining newer compilers.

    Thanks and regards,

    -George

  • George,

    Unfortunately, it isn't as feasible as I'd like; my changes exist on a closed system where a few months could go by without being able to test new versions of software due to a process system. It does make it easier if there was a bug that we could point to and a version that it is fixed in.

    Will
  • Is it the memset issue that doesn't allow inlining? I didn't see a direct symbol reference in the dis-assembly to the memset call.  Also, its not a derived class;  it seems like its auto-generated since my filename had a cpp extension. 
     
    SDSCM00042199 - "Compiler generates unexpected memset call in derived class constructor (affects performance)"

    "In some circumstances, the compiler is needlessly generating a call to memset for some C++ constructor calls when compiling with --abi=eabi (ELF mode). This can inhibit the inlining of simple constructors. "

    Defect occurs in:

    C6000 Compiler versions: 7.2.0B1 - 7.2.6, 7.3.0B1 - 7.3.1

  • I very much doubt it is SDSCM00042199.  

    Let's go back to ...

    ixworks said:
    mvk.S1 0x4064, a3        <<<<  This one changes.     In the previous build when I change code from a different input lib, the STI changes slightly.  The previous was 0x4024,A3 instead.

    It would be good to get a look at the assembly code the compiler generated here.  Build with --src_interlist and find the corresponding statement in the resulting assembly file.  You'll see if this is really a symbolic reference (which I suspect).  If so, what is the symbol?  Did the symbol change, or the address?  There might be some clues in the surrounding assembly code, which will include some compiler generated comments.

    Thanks and regards,

    -George

  • When a function returns a struct, the compiler accomplishes this by creating space for a struct and passing its address in A3, which is not otherwise one of the argument registers. Is it possible that 0x4064 is part of the address of a struct (object, perhaps) that a nearby function will be returning? If so, it is possible for this address to change slightly when some other (possibly unrelated) object or function changes size. Please show us more of the surrounding assembly code. Is this MVK actually in one of the 5 delay slots of the call to __cxa_guard_release? Is it a plain branch, or protected branch? It would help to see the exact disassembly.
  • Archeologist, I've partially answered your request.
    - Added code to show A3 assembly.
    I'm baffled that an auto-created constructor would reference another constructor's memory space.

    Lib1 lives in 0xE026_xxxx (starts at 0x0 offset)

    Lib2 lives in 0xE027_xxxx (starts at 0x0 offset)
     
    TEXT section .image4_text (Big Endian), 0xE0 bytes at 0xE0xx_xxxx.

    E0xx_x100: __sti___19__filename_cpp_fa5f8b8c:

    ...

    b __cxa_guard_acquire.

    ...

    [A0] b __cxa_guard_release


    0xE0260xx  mvk.L2 0,B4
    0xE0260xx  mv.L1 A10, a4
    // newly added to answer question
    0xE0260xx.fphead
    0xE0260xx mvk.S1 0x3dc4, A3 // here's the A3 references
    0xE026080 mkkh.S1 0xE0270000,A3 // it is referencing another library's memory space

  • This is pointing to .far: _ZNSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2ide.
  • This brings me to a broader question:
    I have to move image4's .far section into the main image because the char_traits reference above is in .far for image4, which is a separately loaded image, not the main image that would bootup with.  I'm confused about this, but I'm willing to wash over the nitty-gritty details if there is a compiler/linker setting I'm missing.
     

    But, I've run into many more symbols:  Maklocstr, Sentry_baseD1Ev, LocaleD1Ev...these can't be deleted because I have string processing (sprintfs).  Iostream was removed but localeD1Ev is still there.


     How would I update the linker command file to move these particular functions into one group?

    e.g.
     
    GROUP (main_layout)
    {
    .text (-l=Lib4.lib(.text:_ZSt10_Maklocstr)}   // this is moving lib4's char stuff into the main image. 
    }
     
     
     
    Thanks,

    Will

  • When you say "Lib1 lives in 0xE026_xxxx", that's quite a bit imprecise. A library has many sections including .text and .data sections which might be scattered around in memory. Please generate the linker map file (linker option --map_file=<myexe>.map) and look at all of the occurrences of Lib1 and its sections. You will probably find that the data sections for Lib1 and Lib2 are intertwined to take advantage of the C6000 DP-relative addressing mode.

    A global object constructor may invoke constructors for objects defined in other modules; this is not a problem. In fact, the iostream subsystem has a lot of these cross-file dependences.

    The presence of the ".fphead" instruction tells me you are using C64+ compressed code. It is possible for this code to be in protected or unprotected mode. This is controlled by the encoding of the nearby .fphead instructions. In order to properly interpret what is going on in this sequence of code, we'll need to see an unabridged version of the instructions surrounding the write to A3, including the opcode bits of nearby .fphead instructions. It would be easiest to just tell the compiler to keep the assembly code (--keep_asm) and to cut-and-paste the whole STI function in question to the forum. It will have assembly comments telling us what's going on.

    For some reason, I cannot demangle the section name you presented, but it is clearly a data section involving C++ standard template class num_put, probably template <class _CharT, class _OutputIterator> locale::id num_put<_CharT, _OutputIterator>::id, which is a deep implementation detail.
  • sprintf is a C feature and does not require C++ support features like std::locale.  You must have some other C++ feature in the program which is dragging in iostream support.

    There is no linker option to move all C++ support functions and data as a whole, and because much of the iostream support is C++ templates, these things will usually end up being defined in user code, which will complicate the problem.

    You could perhaps start by moving all .text sections named .text:_Z* from any library to a particular area:

    .text (*.lib(.text:_Z*)}