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.

Questions on TI compiler symbols

(Long post but short question, I added all the information at the end of the post to save you time)

Questions:

The MSP430 TI compiler uses a function in it's initialization process called _auto_init_hold_wtd. This is stored in the .text section, and it's called from the .text:_isr section, specifically from the _c_int00_noargs_noexit function. These can be found in the autoinit.c and boot_special.c files.

I need to ensure that these functions work correctly after relocating them on the RAM. In order to do so, I need to perform the relocations using some compiler symbols. Unfortunately, when I create a relocatable file, all these symbols have a 0 (zero) value and my relocations don't work, thus, the initialization is not correctly executed.

I need to know (1) how many symbols there are, (2) what does each one mean and (3) where they are located (what they point to), so that I can find the best solution to give them the correct values, however, (4) if you can think of any workaround it could also help. Right now, I only know that they are used in functions run_binit, run_cinit and run_pinit functions, called from the _auto_init_hold_wtd function, and, that the symbols of run_cinit are located after an asm routine called __TI_ISR_TRAP from the isr_trap.asm file (it's basically a loop in case the main function finishes).

Information:

_auto_init_hold_wtd()

void AUTO_INIT_HOLD_WDT(void)
{
    run_binit();

    uint16_t initial_WDT = WDTCTL;
    WDTCTL = HOLD_WDT;

    run_cinit();

    WDTCTL = RESTORE_WDT(initial_WDT);

    run_pinit();
}

I could not find run_binit function.

run_cinit()

   /*------------------------------------------------------------------------*/
   /* Process the compressed ELF cinit table. The format is as follows:      */
   /* |4-byte load addr|4-byte run addr|                                     */
   /* |4-byte load addr|4-byte run addr|                                     */
   /*                                                                        */
   /* Processing steps:                                                      */
   /*   1. Read load and run address.                                        */
   /*   2. Read one byte at load address, say idx.                           */
   /*   3. Get pointer to handler at handler_start[idx]                      */
   /*   4. call handler(load_addr + 1, run_addr)                             */
   /*------------------------------------------------------------------------*/
   if (__TI_Handler_Table_Base != __TI_Handler_Table_Limit)
   {
      char *const *table_ptr   = __TI_CINIT_Base;
      char *const *table_limit = __TI_CINIT_Limit;

      while (table_ptr != table_limit)
      {
        char const *load_addr   = *table_ptr++;
        char       *run_addr    = *table_ptr++;
        char        handler_idx = *load_addr++;

        handler_fn_t handler = __TI_Handler_Table_Base[handler_idx];
        handler(load_addr, run_addr);
      }
   }

run_pinit()

   #define PINIT_BASE __TI_INITARRAY_Base
   #define PINIT_LIMIT __TI_INITARRAY_Limit

   /*------------------------------------------------------------------------*/
   /* 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++]();
   }

The symbols I need to perform the relocations, are in the functions above plus some more. Those are the ones I referred to in my questions. Here are some, and the values they had in a test program.

__TI_Handler_Table_Base          0x4448
__TI_Handler_Table_Limit         0x444C
__TI_CINIT_Base                  0x444C
__TI_CINIT_Limit                 0x4454

0x4448: 00B0 0001 4442 0000
0x4450: 2400 0000 FFFF FFFF

However, their value is 0 in the relocations.

Relocation section '.rel.text' at offset 0xa9f4 contains 33 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000002  00055508 R_MSP430X_ABS20_E 0000015c   WDTCTL
00000008  0005550a R_MSP430X_ABS20_E 0000015c   WDTCTL
00000010  0005910b R_MSP430X_ABS20_A 00000000   __TI_Handler_Table_Base   // cinit
00000014  0005920b R_MSP430X_ABS20_A 00000000   __TI_Handler_Table_Limit  // cinit
0000001a  0005930b R_MSP430X_ABS20_A 00000000   __TI_CINIT_Base           // cinit
0000001e  0005940b R_MSP430X_ABS20_A 00000000   __TI_CINIT_Limit          // cinit
0000002a  00059108 R_MSP430X_ABS20_E 00000000   __TI_Handler_Table_Base   // cinit
00000046  00055509 R_MSP430X_ABS20_E 0000015c   WDTCTL
0000004c  0005950b R_MSP430X_ABS20_A 00000000   __TI_INITARRAY_Base       // pinit
00000050  0005960b R_MSP430X_ABS20_A 00000000   __TI_INITARRAY_Limit      // pinit
00000056  0005950b R_MSP430X_ABS20_A 00000000   __TI_INITARRAY_Base       // pinit
00000062  0005960b R_MSP430X_ABS20_A 00000000   __TI_INITARRAY_Limit      // pinit
000000ca  0005550f R_MSP430X_ABS16   0000015c   WDTCTL
000000d0  00037d0f R_MSP430X_ABS16   00000225   PBDIR_H
000000d4  00035f0f R_MSP430X_ABS16   00000204   PADIR_L
000000da  0004370f R_MSP430X_ABS16   00000342   TA0CCTL0
000000e0  00043d0f R_MSP430X_ABS16   00000352   TA0CCR0
000000e6  0004360f R_MSP430X_ABS16   00000340   TA0CTL
000000ec  0004360f R_MSP430X_ABS16   00000340   TA0CTL
000000f0  0005580f R_MSP430X_ABS16   00000000   turn
0000010e  0005860c R_MSP430X_ABS20_A 00000008   _lock
00000112  00056509 R_MSP430X_ABS20_E 00000004   __TI_dtors_ptr
0000011c  0005650c R_MSP430X_ABS20_A 00000004   __TI_dtors_ptr
00000120  00056609 R_MSP430X_ABS20_E 00000000   __TI_cleanup_ptr
00000128  0005660c R_MSP430X_ABS20_A 00000000   __TI_cleanup_ptr
0000012c  0005870c R_MSP430X_ABS20_A 0000000c   _unlock
00000130  0005630c R_MSP430X_ABS20_A 0000023e   abort
0000018e  00059002 R_MSP430_ABS16    00000000   __c_args__
000001ae  00055a0b R_MSP430X_ABS20_A 000000c6   main
00000222  00037a0f R_MSP430X_ABS16   00000223   PBOUT_H
0000022a  00037a0f R_MSP430X_ABS16   00000223   PBOUT_H
0000022e  0005860c R_MSP430X_ABS20_A 00000008   _lock
00000234  0005870c R_MSP430X_ABS20_A 0000000c   _unlock

It can be seen that there are some symbols there with a 0 value, like __TI_cleanup_ptr or __TI_INITARRAY_Base. I need to somehow fix this and I think I think the proper questions to achieve it.

All help is appreciated, thank you.

 

  • Some of those symbols, like __TI_INITARRAY_{Base,Limit} are linker-generated symbols. I don't know what it means to have a relocation in an executable file for a linker-generated symbol. I'd have to think about that for a while.

    Some of these symbols, like __TI_{cleanup,dtors}_ptr, are just normal symbols in the library. They should be dealt with like any other object. The fact that __TI_cleanup_ptr has value 0 is odd, but I can't say that it's wrong. Can you show us the linker map file for this executable?
  • Archaeologist said:
    Some of those symbols, like __TI_INITARRAY_{Base,Limit} are linker-generated symbols. I don't know what it means to have a relocation in an executable file for a linker-generated symbol. I'd have to think about that for a while.

    Okey.

    Archaeologist said:
    Some of these symbols, like __TI_{cleanup,dtors}_ptr, are just normal symbols in the library. They should be dealt with like any other object. The fact that __TI_cleanup_ptr has value 0 is odd, but I can't say that it's wrong.

    I understand, (1) how do you know it ?

    Archaeologist said:
    Can you show us the linker map file for this executable?

    The linker map file, (2) what extension does the file have ? I have a couple of files in my workspace but I don't know which one is the one you are asking for. I think they is a .map and a .ld file. Not sure though and can't check now.

    Thank you.

  • 1) I'm familiar with the source code to the library; I recognized those symbols.
    2) It's the file specified by the linker option --map_file. By convention, it has a .map extension
  • I guess it's this one. I changed the extension since the forum doesn't let me post .map files.

    BlinkingLedTimer.txt

    Is it useful for you ?

  • A bit. This is really strange; your program is so small, it does not call exit, so it should not have any references to __TI_dtors_ptr, and in fact the list of symbols in the map file agrees with me. However, your table of relocations still has a reference to it; I'm not sure why.

    By far the most bizarre thing is that your table shows relocations at offsets as high as 0x234 in the .text section, but the map file says your .text section is only 0xec long. Are you sure you got this relocation table out of the executable file?
  • Archaeologist said:
    Are you sure you got this relocation table out of the executable file?

    I have two configurations, Debug and Release, Debug is the relocatable one, so maybe you are right and I uploaded the wrong map file (Release). I will come back with the other map file.

    Thank you.

  • I think I have the correct one now.

    7002.BlinkingLedTimer.txt

  • Okay, this one matches. Look in the map file at the following symbols, and notice that they are all "UNDEFED":

    __TI_CINIT_Base __TI_CINIT_Limit __TI_Handler_Table_Base __TI_Handler_Table_Limit __TI_INITARRAY_Base __TI_INITARRAY_Limit __c_args__

    These are all special linker-generated symbols, and it is OK for them to be undefined. The linker will use a value of 0 if these are ever referred to in the object file (they are), indicating that these features are unused and not present. Because you are forcing the linker to keep the relocations, there will still be a relocation for each of these symbols, even though the value is 0. It should be harmless for you to process these relocations, because you'll only add zero to the existing field. I don't think you need to handle these any differently than the other relocations. Were you encountering some sort of problem if you let your relocation handler process them?
  • It is a problem, yes.

    For example, giving the code in this other post of mine in the bottom (after the EDIT), there is a global variable named turn. The relocations I posted here, were taken from the dump of that code. This means, the initialization of globar variables is needed for turn to work. However, if both values (base and limit) are 0, there will be no initialization performed.

    (I am supposing both symbols have the same stndx, I can't check it now)

    Hope it makes sense.

  • According to your latest linker command file, .cinit is of length 0, which means it is correct for __TI_CINIT_Base and __TI_CINIT_Limit to have the value 0. What you should be asking is why .cinit is of length 0. I can't immediately discern why. What are your complete linker options? Make sure you are not using --zero_init=off
  • I checked, I am not using --zero_init=off.

    Moreover, I ensured I did not send the wrong file again, and I found out this in the symbol dump:

    Symbol table '.symtab' contains 1431 entries:
       Num:    Value  Size Type    Bind   Vis      Ndx Name
         0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
         1: 00000000     0 SECTION LOCAL  DEFAULT    5 .bss
         7: 00000000     0 SECTION LOCAL  DEFAULT   11 .cinit
      1368: 00000000     2 COMMON  GLOBAL HIDDEN     5 turn
      1423: 00000000     0 NOTYPE  GLOBAL HIDDEN   UND __STACK_END
      1424: 00000000     0 NOTYPE  GLOBAL HIDDEN   UND __c_args__
      1425: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_Handler_Table_Base
      1426: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_Handler_Table_Limit
      1427: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_CINIT_Base
      1428: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_CINIT_Limit
      1429: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_INITARRAY_Base
      1430: 00000000     0 NOTYPE  WEAK   HIDDEN   UND __TI_INITARRAY_Limit

    This proves that my turn variable exists, but the initialization tables are empty. (1) Does this make sense ? Maybe I didn't set a value to the global turn variable in that version of the program (not even 0), so I will check and come back after having a look at it. That's all I can think of.

    Also, I want to link another post of mine, directly related to the question of the topic on compiler symbols. In there, I talk about setting a value to __STACK_END in order the relocations to work. One of the goals of this tread was to know (2) what other symbols do I have to initialize so that the relocation is performed correctly.

    Thank you.

  • 1) No, it does not immediately make sense for EABI. In EABI, assuming you are linking with C ROM or C RAM model, uninitialized global variables are supposed to be initialized to 0. You have an uninitialized global variable, so .cinit should not be empty. This is not necessarily a bug; there are several things that can disable global variable initialization, one of them being --zero_init=off. I do not know in this case why .cinit is empty.
    2) I don't know. You're pretty far away from supported use cases, and I don't really know if what you want to do can be done with what the linker gives you. I've been trying to answer your questions with what spare time I can find, but you're past the details that I know offhand; I'd have to research the source code to figure out further answers, and I'm not going to be able to justify the time to do so.