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/MSP430F5510: Linker relocating constants into non-existent address range

Part Number: MSP430F5510

Tool/software: TI C/C++ Compiler

For some reason, all of a sudden, the linker has decided to relocate constants into a black hole.

Here's the layout in the linker cmd file in my project:

MEMORY
{
    SFR                     : origin = 0x0000, length = 0x0010
    PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
    PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
    RAM                     : origin = 0x2400, length = 0x1000
    USBRAM                  : origin = 0x1C00, length = 0x0800
    INFOA                   : origin = 0x1980, length = 0x0080
    INFOB                   : origin = 0x1900, length = 0x0080
    INFOC                   : origin = 0x1880, length = 0x0080
    INFOD                   : origin = 0x1800, length = 0x0080
    FLASH                   : origin = 0x8000, length = 0x7F80
    INT00                   : origin = 0xFF80, length = 0x0002
    INT01                   : origin = 0xFF82, length = 0x0002
    INT02                   : origin = 0xFF84, length = 0x0002
    INT03                   : origin = 0xFF86, length = 0x0002
    INT04                   : origin = 0xFF88, length = 0x0002

Here's the trivial definition in main.cxx:

const char banner[] = "Test board Rev 2";

Here's what the memory browser shows:

banner
FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF
FFFF	FFFF
USBTMC<USBTMC_AppDelegate>::bulk_dev_req()::string
FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF
USBTMC<USBTMC_AppDelegate>::service()::string (instance 6)
FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF	FFFF
evmap


With "banner" relocated to 00A2A2.
This is a hole!
Many if not ALL other constants seem to have ended up there as well.

This just suddenly started today and I have no idea why it does this. It says nothing when building

It doesn't get far; just prints garbage and get stuck at 3fff (since vtables end up there as well).

Also tried adding __attributes__((section (".const:))) to it definition, but this makes no difference.

Checking with nm on OS X (recompiled, so things moved a bit):
$ nm protoboard5510.out | fgrep banner
0000a09c b banner
$

Linker map:

******************************************************************************
                  MSP430 Linker Unix v16.9.4
******************************************************************************
>> Linked Fri Jan 26 02:18:32 2018

OUTPUT FILE NAME:   <protoboard5510.out>
ENTRY POINT SYMBOL: "_c_int00_noargs"  address: 00009f2c


MEMORY CONFIGURATION

         name            origin    length      used     unused   attr    fill
----------------------  --------  ---------  --------  --------  ----  --------
  SFR                   00000000   00000010  00000000  00000010  RWIX
  PERIPHERALS_8BIT      00000010   000000f0  00000000  000000f0  RWIX
  PERIPHERALS_16BIT     00000100   00000100  00000000  00000100  RWIX
  INFOD                 00001800   00000080  00000000  00000080  RWIX
  INFOC                 00001880   00000080  00000000  00000080  RWIX
  INFOB                 00001900   00000080  00000000  00000080  RWIX
  INFOA                 00001980   00000080  00000000  00000080  RWIX
  USBRAM                00001c00   00000800  00000000  00000800  RWIX
  RAM                   00002400   00001000  00000278  00000d88  RWIX
  FLASH                 00008000   00007f80  00002662  0000591e  RWIX
  INT00                 0000ff80   00000002  00000000  00000002  RWIX
  INT01                 0000ff82   00000002  00000000  00000002  RWIX
  INT02                 0000ff84   00000002  00000000  00000002  RWIX
  INT03                 0000ff86   00000002  00000000  00000002  RWIX
  INT04                 0000ff88   00000002  00000000  00000002  RWIX
  INT05                 0000ff8a   00000002  00000000  00000002  RWIX
  INT06                 0000ff8c   00000002  00000000  00000002  RWIX
  INT07                 0000ff8e   00000002  00000000  00000002  RWIX
  INT08                 0000ff90   00000002  00000000  00000002  RWIX
  INT09                 0000ff92   00000002  00000000  00000002  RWIX
  INT10                 0000ff94   00000002  00000000  00000002  RWIX



So, where is that address even coming from? Why is it putting constants in a hole?

I've tried both small and large memory models, too. Makes no difference!

  • Man, this forum software is REALLY terrible... code blocks seem to suck in random text.
  • Actually, it's not a hole - I forgot the 5510 has 32k flash. But why isn't there anything there...
  • I changed the string back to its original banner and recompiled:

    const char banner[] = "Protoboard5510 Rev 2";

    I enabled the hex dump and can find the string there. The IDE says the symbol "banner" is at A092 . But in the hex dump it's at at, eh, A3C1...
    %4E69280000A3C001FF50726F746F626F61FF7264353531302052FF6576203200004A42FF204445

    Dividing the tekhex record:
    %4E 6 92 80000A3C00 1FF50726F746F626F61FF7264353531302052FF6576203200004A42FF204445

    The string is "Protoboard" which is 50726F74... Checking with the memory browser I find the string at that location.
    From the memory browser, 8 bit hex:

    0x00A3C0 01 FF 50 72 6F 74 6F 62 6F 61 FF 72 64 35 35 31 30 20 52 FF 65 76 20 32 00 00 4A 42 FF 20 44 45
    ASCII:
    0x00A3C0 . . P r o t o b o a . r d 5 5 1 0 . R . e v . 2

    Now, not ONLY is it in the wrong place, but it has gotten arbitrary FFs inserted?!

    Maybe this is happening more broadly, and the linker has inserted FFs when producing the output... causing it to shift relative to the symbol tables?
  • I would like to reproduce the issue.  For that, I need you to send your CCS project.  Please see the article Project Sharing to learn how to create the zip file.  Then attach that to your next post.

    If you don't feel comfortable with that ... I might be able to shed some light if I had the final .out executable file, the linker map file, and the linker command file.  Put those files together in one zip and attach to your next post.

    Thanks and regards,

    -George

  • I did some more testing, pulled the repo on a Windows computer and built it there - same thing in the hex output.  Except on Windows I got random FBs in addition to FFs.

    I then discovered there's a newer compiler version, so I switched from 16.9.4.LTS to 16.9.6.LTS and tried again, again on Windows, and no change.

    However, I did notice when looking closer at the .map file from the linker that the data I'm looking at is in .cinit!  So maybe it makes sense in some weird way, and the memory iniitializer wants aligned blocks or something, and so they get padded.  But the symbol is in .const - why would this be added to the .cinit table?  So my further guess is the initializer tries to copy from .cinit to flash, which of course won't work and it's now effectively FFs.

    Looking at the compiler guide PDF, it says v17.9.0.STS!  But I don't see this available to pick in TI-CCS, and when I check for updates it says there aren't any.  I assume this means I have to manually install it...

    I'll do some diagnostics and if I can't figure this out will zip it up...

  • Let's see if works to post this time...

    I found the root cause of this.  I had a single constant explicitly put in the ".const" section, along the lines of:

    #define _const_ __attribute__((section (".const")))
    
    const struct { int x; } foo _const_ = { 17 };
    
    const string s[] = "hello, world";
    

    This puts 'foo' in .text with an initializer in .cinit.  But it's pretty random; I've seen it end up elsewhere as well.

    Not only does this constant get messed up, but other constants randomly get the same treatment.  So it's enough to have ONE of these someplace, to cause constants to get moved to .text with initializers in .cinit.

  • When I try your three-line example in MSP430 16.9.6.LTS, with no command-line options, it puts foo into section ".const" with no .cinit record. What compiler command-line options are you using when you see a .cinit initializer show up for foo?

    There should not be any random behavior; it may be complex, but it should be deterministic.