- ARM link/load problem
- Posted by Not Really Me on January 19th, 2005
Using CW for ARM developer suite V1.2.
The piece of code below works correctly if there is no split memory
specified in the link command. Linked at 0x05000000 there are no problems.
If the code is linked at RO Base 0x05000000 and RW Base 0x02000000, the load
is not initialized correctly. The wrong data gets copied to the RW base and
a data error occurs on the 4th printf. Is this a bug, or does it need to
have scatter loading specified?
I have tried a scatter load file, but I don't think it was correct. If it
needs a scatter file please show an example that should work.
Thanks,
Scott
/*
* File: main.c
* Purpose: sample program
*
*/
#include <stdio.h>
#include <string.h>
#define SIZE 4
const char *sprintffmt[SIZE] = /* sprintf format strings */
{ "%s\n", /* 0 */
"%s%s\n", /* 1 */
"%s%s%s\n", /* 2 */
"%s%s\n"}; /* 3 */
#define INDEX 0 /* Output buffer filename */
char buff[]; /* output stream buffer */
int main()
{
// sprintffmt[INDEX] = "%s";
strcpy(buff, "This is a test\n");
printf("\nAddr of sprintffmt = %x \n", sprintffmt ); // 0x02000000
printf("\nAddr of sprintffmt = %x \n", &sprintffmt[INDEX] ); //
0x02000000
printf("\nAddr of sprintffmt = %x \n", sprintffmt[INDEX] );
printf(sprintffmt[INDEX], buff);
return 0;
}
- Posted by Hans-Bernhard Broeker on January 19th, 2005
Not Really Me <scott@exoxyztech.com> wrote:
Seeing this line appear at file scope:
I rather seriously doubt that.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
- Posted by Not Really Me on January 19th, 2005
Hans-Bernhard Broeker wrote:
Sorry, caught by a cut and paste error in my haste to put the post together.
In this simple test the array got allocated at the end of the variables, so
it worked fine without hitting anything else. The original code is built
and run regularly on at least 8 different compiler/processor combinations.
The problem as described still exits.
Scott
- Posted by Tauno Voipio on January 20th, 2005
Not Really Me wrote:
OK.
Now, repair your cut-and-paste so that it compiles
and exhibits the undesired behaviour as posted, without
any modifications, and post the code.
--
Tauno Voipio
tauno voipio (at) iki fi
- Posted by Not Really Me on January 20th, 2005
Tauno Voipio wrote:
The only change was filling in a value for the buff array and removing the
commented out line of code.
If the code is linked at RO Base 0x05000000 and RW Base 0x02000000, the load
is not initialized correctly. The wrong data gets copied (by the C runtime
initialization) to the RW base and a data error occurs on the 4th printf.
Is this a bug, or does it need to have scatter loading specified?
Without a RW Base specified the output is:
Addr of sprintffmt = 05001a84
Addr of &sprintffmt[INDEX] = 05001a84
Addr of sprintffmt[INDEX] = 05001908
This is a test
With the RW Base specified as 0x02000000 the output should be:
Addr of sprintffmt = 02000000
Addr of &sprintffmt[INDEX] = 02000000
Addr of sprintffmt[INDEX] = 05001908
This is a test
If I run the second test directly after the first it works fine!. If I
power off the board to erase all the ram and run only the second test I get:
Addr of sprintffmt = 02000000
Addr of &sprintffmt[INDEX] = 02000000
Addr of sprintffmt[INDEX] = 4bf7c776
Followed by a Data Abort error from Codewarrior.
Somehow the first load makes the second test work correctly. The first test
does not need to be run, only loaded.
BTW, the debugger is an ARM MultiICE under CodeWarrior.
/*
* File: main.c
* Purpose: sample program
*
*/
#include <stdio.h>
#include <string.h>
#define SIZE 4
const char *sprintffmt[SIZE] = /* sprintf format strings */
{ "%s\n", /* 0 */
"%s%s\n", /* 1 */
"%s%s%s\n", /* 2 */
"%s%s\n"}; /* 3 */
#define INDEX 0 /* Output buffer filename */
char buff[128]; /* output stream buffer */
int main()
{
strcpy(buff, "This is a test\n");
printf("\nAddr of sprintffmt = %p \n", sprintffmt );
printf("\nAddr of &sprintffmt[INDEX] = %p \n", &sprintffmt[INDEX] );
printf("\nAddr of sprintffmt[INDEX] = %p \n", sprintffmt[INDEX] );
printf(sprintffmt[INDEX], buff);
return 0;
}