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.

TMS320F28388D: Get name, size, and address of all variables from .out file

Part Number: TMS320F28388D

Hello there,

I'm looking into the possibilities to get a list of all global and static variables that are in my application, with their name, size, and address.

The .map file provides some info, but not for static variables. I had a look at tools like readelf, objdump, dwarfdump, but as far as I can see they can't produce the list I need.

Then I found the TI nm2000 tool which seems to provide the information I need. When I test with this code:

typedef struct
{
    uint32_t ui32;
    uint16_t ui16;
    uint8_t  ui8;
} T_TEST_STRUCT;

uint8_t Test_ui8_glob;
uint8_t Test_ui8_glob_init = 0;
static uint8_t Test_ui8_stat;
static uint8_t Test_ui8_stat_init = 0;

uint16_t Test_ui16_glob;
uint16_t Test_ui16_glob_init = 0;
static uint16_t Test_ui16_stat;
static uint16_t Test_ui16_stat_init = 0;

uint32_t Test_ui32_glob;
uint32_t Test_ui32_glob_init = 0;
static uint32_t Test_ui32_stat;
static uint32_t Test_ui32_stat_init = 0;

T_TEST_STRUCT Test_struct_glob;
T_TEST_STRUCT Test_struct_glob_init = { 0, 0, 0 };
static T_TEST_STRUCT Test_struct_stat;
static T_TEST_STRUCT Test_struct_stat_init = { 0, 0, 0 };

And then run "nm2000 -l mytest.out", I get this result:

[index]  value      size  bind  type  vis   shndx  symbol name 
...
...
[25332] |0x200100ac|8|GLOB |COMN |HIDN |14    |Test_struct_glob
[25334] |0x20010830|8|GLOB |OBJT |HIDN |13    |Test_struct_glob_init
[83]    |0x2001008c|8|LOCL |OBJT |HIDN |14    |Test_struct_stat
[84]    |0x20010838|8|LOCL |OBJT |HIDN |13    |Test_struct_stat_init
[25330] |0x2001011e|2|GLOB |COMN |HIDN |14    |Test_ui16_glob
[25341] |0x20010746|2|GLOB |OBJT |HIDN |13    |Test_ui16_glob_init
[79]    |0x2000feda|0|LOCL |OBJT |HIDN |14    |Test_ui16_stat
[80]    |0x20010748|2|LOCL |OBJT |HIDN |13    |Test_ui16_stat_init
[25331] |0x200100cc|4|GLOB |COMN |HIDN |14    |Test_ui32_glob
[25342] |0x2001074c|4|GLOB |OBJT |HIDN |13    |Test_ui32_glob_init
[81]    |0x2000fedc|0|LOCL |OBJT |HIDN |14    |Test_ui32_stat
[82]    |0x20010750|4|LOCL |OBJT |HIDN |13    |Test_ui32_stat_init
[25329] |0x20010123|1|GLOB |COMN |HIDN |14    |Test_ui8_glob
[25339] |0x20010744|1|GLOB |OBJT |HIDN |13    |Test_ui8_glob_init
[77]    |0x2000fed8|0|LOCL |OBJT |HIDN |14    |Test_ui8_stat
[78]    |0x20010745|1|LOCL |OBJT |HIDN |13    |Test_ui8_stat_init
...
...

Most of this is OK, except when a variable is defined as static and not initialized. Then the size appears as 0. In all other cases the correct size is shown, even for an uninitialized static struct.

What is the cause of this behavior?

Also, what is the meaning of the nm2000 output fields 'index', 'vis', and 'shndx'? I couldn't find any documentation about it.

Other than the issue with uninitialized static variables, the nm2000 tool seems to fulfill my requirements. But if you have any suggestions for other tools that could do the same, please let me know.

Thanks and kind regards,
Arjan

  • The type name uint8_t is not supported by the C2000 compiler.  You built this code with the C2000 compiler?  Or another compiler?

    Thanks and regards,

    -George

  • Hello George,

    In this case I'm working on the CM core of the F28388D, so it's the ARM compiler: ti-cgt-arm_20.2.7.LTS. And uint8_t is a typedef in _stdint.h. But that doesn't really matter for this issue because it's about getting variable information from an ELF/DWARF output file.

    I did notice I get similar results when using the readelf tool to read the symbol table:

       Num:    Value  Size Type    Bind   Vis      Ndx Name
    ...
        77: 2000fed8     0 OBJECT  LOCAL  HIDDEN    14 Test_ui8_stat
        78: 20010745     1 OBJECT  LOCAL  HIDDEN    13 Test_ui8_stat_init
        79: 2000feda     0 OBJECT  LOCAL  HIDDEN    14 Test_ui16_stat
        80: 20010748     2 OBJECT  LOCAL  HIDDEN    13 Test_ui16_stat_init
        81: 2000fedc     0 OBJECT  LOCAL  HIDDEN    14 Test_ui32_stat
        82: 20010750     4 OBJECT  LOCAL  HIDDEN    13 Test_ui32_stat_init
        83: 2001008c     8 OBJECT  LOCAL  HIDDEN    14 Test_struct_stat
        84: 20010838     8 OBJECT  LOCAL  HIDDEN    13 Test_struct_stat_init
    ...
     25329: 20010123     1 COMMON  GLOBAL HIDDEN    14 Test_ui8_glob
     25330: 2001011e     2 COMMON  GLOBAL HIDDEN    14 Test_ui16_glob
     25331: 200100cc     4 COMMON  GLOBAL HIDDEN    14 Test_ui32_glob
     25332: 200100ac     8 COMMON  GLOBAL HIDDEN    14 Test_struct_glob

    For some reason a static (local) uninitialized variable always shows with size 0.

    Kind regards,
    Arjan

  • I can reproduce the same result.  I don't know why the size field for an uninitialized static variable is 0.  Thus, I filed EXT_EP-11390 to have this investigated.  You are welcome to follow it with that link.

    Consider this question.  Given this error, how does Code Composer Studio still know the correct size of these variables?  Because it doesn't rely on the size field of the symbol table entry.  Instead, it gets information about the type of the variable from the Dwarf debug part of the object file.  And that type information contains within it the size of the variable.  This being the case, you have to consider the possibility of yet other cases where the size field of the symbol table entry is not as expected.

    Here is yet another way to gather symbol information.

    armofd -x --obj_display=none,symbols -o file.xml file.obj

    Here are a few lines from file.xml.

                      <elf32_sym>
                         <index>0x1d</index>
                         <st_name>0xe8</st_name>
                         <st_name_string>global_variable</st_name_string>
                         <st_value>0x4</st_value>
                         <st_size>0x4</st_size>
                         <st_bind>STB_GLOBAL</st_bind>
                         <st_type>STT_COMMON</st_type>
                         <st_visibility>STV_HIDDEN</st_visibility>
                         <st_shndx>SHN_COMMON</st_shndx>
                      </elf32_sym>

    Automated processing of XML is usually easier.

    The command armofd is the object file display utility.  It is documented in the TI ARM assembly tools manual.

    Thanks and regards,

    -George

  • Thanks for filing the issue, I will keep an eye on it.

    I tried the armofd utility (and ofd2000 as well), still the same result with size is 0x0 for uninitialized static variable:

                      <elf32_sym>
                         <index>0x4d</index>
                         <st_name>0x45b</st_name>
                         <st_name_string>Test_ui8_stat</st_name_string>
                         <st_value>0x2000fed8</st_value>
                         <st_size>0x0</st_size>
                         <st_bind>STB_LOCAL</st_bind>
                         <st_type>STT_OBJECT</st_type>
                         <st_visibility>STV_HIDDEN</st_visibility>
                         <st_shndx>0xe</st_shndx>
                         <st_shndx_string>.bss</st_shndx_string>
                      </elf32_sym>

    I didn't try with the C28x compiler yet, we will need the same variable information from the CPU1 and CPU2 cores of the F28388D as well for the runtime monitoring tool we want to create.

    For now I can use a workaround by simply initializing all variables we might want to monitor at runtime. At least that's easier than writing my own DWARF parser.

    Thanks and kind regards,
    Arjan

  • FYI the result is the same with the C28x compiler:

        33: 0000a801     0 OBJECT  LOCAL  HIDDEN     6 Test_ui8_stat
        34: 0000a821     2 OBJECT  LOCAL  HIDDEN    10 Test_ui8_stat_init
        35: 0000a803     0 OBJECT  LOCAL  HIDDEN     6 Test_ui16_stat
        36: 0000a823     2 OBJECT  LOCAL  HIDDEN    10 Test_ui16_stat_init
        37: 0000a806     0 OBJECT  LOCAL  HIDDEN     6 Test_ui32_stat
        38: 0000a826     4 OBJECT  LOCAL  HIDDEN    10 Test_ui32_stat_init
        40: 0000a80c     0 OBJECT  LOCAL  HIDDEN     6 Test_struct_stat
        41: 0000a82c     8 OBJECT  LOCAL  HIDDEN    10 Test_struct_stat_init
       774: 0000a828     8 OBJECT  GLOBAL HIDDEN    10 Test_struct_glob_init
       775: 0000a804     4 OBJECT  GLOBAL HIDDEN     6 Test_ui32_glob
       776: 0000a800     2 OBJECT  GLOBAL HIDDEN     6 Test_ui8_glob
       778: 0000a820     2 OBJECT  GLOBAL HIDDEN    10 Test_ui8_glob_init
       779: 0000a822     2 OBJECT  GLOBAL HIDDEN    10 Test_ui16_glob_init
       780: 0000a802     2 OBJECT  GLOBAL HIDDEN     6 Test_ui16_glob
       781: 0000a808     8 OBJECT  GLOBAL HIDDEN     6 Test_struct_glob
       782: 0000a824     4 OBJECT  GLOBAL HIDDEN    10 Test_ui32_glob_init

  • I updated the record to note that it occurs with the C2000 compiler as well.

    Thanks and regards,

    -George