This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ld generates invalid addresses

Dear readers,

I ran into problems linking a C/C++ program for the STM32F4 (which is a Cortex-M4F, ARMv7) mikrocontroller using the gcc-arm toolchain on Windows. Since only the program memory (flash) of the controller can be programmed, the linker should generate a single section ending up in the flash, consisting of the program data, the program code and the necessary startup code to load the data into the RAM.
I used the example code from ST for the linker script and startup assembly code. This worked well first, until suddenly, after doing a tiny modification to the code, strange behaviour occured, which is a result of global variables being initialized incorrectly. The reason is:
As instructed by the linker script, ld concatenates the ISR Vector, the program code (including the startup code), the three arrays preinit_array, init_array, fini_array and the initialization data. ld generates three labels:
- _sidata is a pointer to the beginning of the initialization data in the program memory ( = flash)
- _sdata is a pointer to the RAM, where the initialization data should be placed before main() is called
- _edata points to the end of that data, thereby determining its size.

Upon startup, the controller executes the startup code, which effectively does a memcpy (_sdata, _sidata, _edata - _sdata); (written in assembly language, but this way it's shorter), which should initialize all global variables with the initialization data from the program memory. The problem is now, that the _sidata label is set incorrectly - in my case, the initialization data in the flash begins at addess 0x080021b0 (placed there by ld), so ld should set _sidata to exactly that address, but it sets it to 0x080021ac. This address points into the fini_array, so the startup code copies that data into the RAM, corrupting all global variables. I have no idea why ld does that, can anyone help me with that?

My code can be found at and compiled by "ruby build.rb" (which requires the ruby interpreter). The build.bat can also be used to do that. Compiling should also be possible on Linux. In the 'Debug' directory, i included the compiled code in ELF, ihex and binary format and the disassembly, where you can see that _sidata got the wrong address.
The C/C++ Code is unfinished and of not much use, as I can't continue programming with ld failing that way...

Any help would be very much appreciated, thank you in advance!

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]