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.

Get data from .out-file

Hi, is it possible to get some static data from an .out-file?

I want to read out the data from a struct, containing some strings and numbers. I know the name of the variable, and if necessary, I can also define the location (but by name is ideal).

I want to use this to store and retrieve version information.

Example:

#include "version_info-auto.h"
#include <stdint.h>

struct version_info_t {
const char magic_header[8];
const uint32_t compile_date;
const uint16_t compile_time;
const uint32_t compiler_version;
const uint16_t program_id;
const char version_tag[9];
const char magic_trailer[7];
};


#pragma DATA_SECTION(version_info, "version_info")
const struct version_info_t version_info = {
.magic_header = "header1",
.compile_date = COMPILE_DATE,
.compile_time = COMPILE_TIME,
.compiler_version = __TI_COMPILER_VERSION__,
.program_id = PROGRAM_ID,
.version_tag = VERSION_TAG,
.magic_trailer = "trail1"
};

  • Stian Soevik said:
    is it possible to get some static data from an .out-file?

    Yes, it's possible.  It is straightforward, but detailed.

    The general idea is to obtain these three pieces of information related to the symbol and the section which contains the data associated with the symbol.

    • sect_file_ptr: The file offset of where the section starts in the final linked executable .out file
    • sym_addr: The address of the symbol
    • sect_base: The base address of the section 

    Then you compute the expression: sect_file_ptr + (sym_addr - sect_base) .  That number tells you exactly which offset in the file contains the data you want.

    I'll do a simple example to show the concept.  I'll do it with C2000 tools.  Because C2000 is not 8-bit byte addressable, things are a bit more complicated.  But I think this is the CPU architecture you are using.

    Here is the file ...

    C:\dir>type main.c
    #include <stdint.h>
    struct version_info_t {
       char header[8];
       uint32_t id;
    };
    #pragma DATA_SECTION(unrelated_string, "custom_section")
    const char unrelated_string[] = "str";
    #pragma DATA_SECTION(version_info, "custom_section")
    const struct version_info_t version_info = {
       .header = "header1",
       .id     = 0x1111
    };
    void main() {}

    Build it ...

    C:\dir>cl2000 -al -v28 -ml --gcc main.c -z -o main.out
    <Linking>

    You can get sect_file_ptr and sect_base from this command ...

    C:\dir>ofd2000 --obj_display=none,sections -v main.out

    We need the information for the section custom_section, which is:

       <10> "custom_section"
          Load Address:        0x000000d6  Run Address:        0x000000d6
          Size:                0xe         Alignment:          2
          Loaded Onto Device:  Yes         Address Unit Size:  16 bits
          File Offset:         0x00001143  # Relocs:           0
          Reloc File Offset:   0x00000000  # Lines:            0
          Line File Offset:    0x00000000  TI-COFF s_flags:    0x00000040
          TI-COFF s_flag:      STYP_DATA

    The sect_file_ptr is the field File Offset 0x1143 and the sect_base is the field Run Address 0x00d6.

    Now you need the address of the symbol.  Here is how to get that ...

    C:\dir>nm2000 -l main.out | fgrep version_info
    [96]    |0x000000da|C_EXT   |custom_section     |_version_info

    That shows the address of _version_info is 0x00da, and it is in the section named custom_section.  

    I over-simplified when I showed the expression for computing the file offset.  It is actually this: sect_file_ptr + 2 * (sym_addr - sect_base) .  Note the addition of "2 *".  The C2000 addresses are in terms of C2000 16-bit bytes, but we need the 8-bit byte offset into the file.  So, you have to multiply that delta times two.  I'll let you run all the math.  It comes to 0x114b.

    There are several ways you can look at a binary file.  Here I use the od (object dump) command from Cygwin (which borrows it from Unix) ...

    C:\dir>od -A x -j 0x114b -N 14 -t c -w1 main.out
    00114b   h
    00114c  \0
    00114d   e
    00114e  \0
    00114f   a
    001150  \0
    001151   d
    001152  \0
    001153   e
    001154  \0
    001155   r
    001156  \0
    001157   1
    001158  \0

    I don't want to describe all the options to od.  The important one is -j, which is the offset in the file where the dump begins.  Note how a \0 separates each character.  This is another artifact of 16-bit bytes on C2000.

    Hope this helps ...

    -George

  • Great answer, thanks a lot! You are correct, I use C2000. My next question is if this is possible with a file read from a target (e.g. via Tools > Save Memory in Code Composer). I suppose we don't have the same symbol information, but then it is OK to specify location if necessary (e.g. by #pragma DATA_SECTION).

  • Stian Soevik said:
    if this is possible with a file read from a target (e.g. via Tools > Save Memory in Code Composer)

    I don't specifically know, but I doubt it.  That file would need to contain the symbol information I mention above.  I doubt it is present.

    Thanks and regards,

    -George 

  • I mean without the symbol information, if we know the location of the data. That would be an OK solution. Maybe it's enough to dump the data from Code Composer, and use a hex editor to look at the specified location?

  • Sounds like it is worth a try.  I would start with a small example.

    Thanks and regards,

    -George