[ECOS] (arm-elf) pointers to items in .data section incorrect after loading

Eric de Jong list_ericdejong_10@gmx.net
Thu Jan 22 07:50:00 GMT 2004


>> Next, I loaded the program with Redboot. It reported the code was loaded at
address 0xac00
>> I'm probably doing something wrong.

You compiled your code to be run from address 0, so you must run it from address
0. To change this behaviour, change your linker script, so your code starts from
another address.

I do not think the c-compiler can generate position independent code (anymore? I
remember there was a compiler switch for it). You might try putting the data
string in the code section to create position independed code:

1> const char * str1 = "Electric Eye" __attribute__ ((section (".text")))

Why would you want to load your program with the redboot command interface? To
debug an application, use gdb/insight. To run an application standalone, compile
it as romram target and burn it to flash/eprom.

Eric.

----- Original Message -----
From: "George J. Pantazopoulos" <robotics@gammaburst.net>
To: <ecos-discuss@sources.redhat.com>
Sent: Thursday, January 22, 2004 8:03 AM
Subject: [ECOS] (arm-elf) pointers to items in .data section incorrect after
loading


Hey group,

      I'm a newbie developing for an ARM7 target (the Atmel EB40A). I have
a LCD
character display hooked up to it using my own drivers.

I have Redboot [ROM] installed on the EB40A, which is used as a bootloader and
debug monitor. Redboot uses locations 0x0000 thru 0xa960 of my board's 256K RAM

      My problem is that the simple C program (Figure 1) runs incorrectly
after
being loaded and run by Redboot (via the 'go' command). The baffling thing is
that it worked perfectly in the debugger, but when actually loaded by Redboot
and run, line 5 printed garbage while line 6 still printed the 'a' properly.

Figure 1 - chartest.c
= Begin Code snippet =
1> const char * str1 = "Electric Eye";
2>
3> int main()
4> {
5>  LCDPutChar(  str1[0] );
6>  LCDPutChar(  'a' );
7>
8>  return 0;
9> }
= End Code Snippet =

      I'm using gcc-3.2.1, binutils-2.13.1, newlib-1.11.0, and insight-5.3 and
I've compiled my test program with -nostdlib -nostartfiles and -nodefaultlibs.
(I have a simple crt0.S that inits the stack and fp and calls main() ).

      The linker script starts at address 0x0000. (Yes, I know that when
debugging I have to change this to something above 0xa960 so I won't trample
over the RAM used by Redboot. That's not the problem here).



      I did a lot of investigation and discovered why it doesn't run properly.
Unfortunately, I don't know how to deal with what I found.

      First, I examined the executable with objdump and found that .text
starts
at 0x0000, and .data starts at 0x0528 (the first and only item in .data is the
string "Electric Eye". Everything is ok here.

      Next, I loaded the program with Redboot. It reported the code was loaded
at address 0xac00. After poking around with the memory 'dump' command, I
confirmed that the sections themselves were correctly relocated, as expected.
For example, section .text was loaded in RAM at 0xac00 (0x0000 + 0xac00).
section .data was correctly loaded at 0xb128 (0x0528 + 0xac00). (Doing a dump
of location 0xb128 revealed the string "Electric Eye" in the dumped output).
Again, everything is ok so far.

      To my horror however, I found that at runtime the pointer 'str1' has the
incorrect (non-relocated) value of 0x0528! I ascertained this by having my LCD
print the value of 'str1' at runtime.

The correct value of this pointer should have been 0xb128 ( 0x0528 + 0xac00 ).


      Then I discovered why the pointer address couldn't have been
relocated. I
examined the output of objdump some more:

<.text>
0000:  (code...)
   ...
02cc:  ldr r3, [pc, #164]   ;gcc loads into r3 the contents of pc+164 (0x378)
02d0:  str r3, [r11, #-16]  ;r3 used as a pointer to store a value in the
frame.
   ...
   ...  (much more code)
   ...
0374:  ldmb fp, {fp,sp,pc}  ;a return from some function
0378:  0x0528               ;The problem! This can not get adjusted at runtime!
037C:  (more code here)
   ...
   ...  (etc)
   ...
0x524: (end of .text)

<.data>
0x528: "Electric Eye"       ;

      The string lives at the start of the .data section, at 0x0528.

      Basically, the string's *pointer* is itself stored in a pool location
(wedged in bewteen two functions). It is accessed as pc+164, which works
out to
0x378 using the 0x0000 starting address. We'll just call it 0x0378 here for
simplicity's sake, but this value WILL change at runtime, as it should. Note
the two levels of indirection. 0x0378 is a pointer to a pointer.

      The value 0x0528 (stored at 0x0378) is the location of "Electric Eye" in
section .data. Unfortunately, at runtime .data is mapped to 0xb128 (0x0528
+ 0xac00)
However, location pc+164 will STILL contain 0x0528 - the wrong value! It
needed
to be adjusted upward by 0xac00 to compensate for the runtime load address. I
don't see how this can be done in a straightforward way at all, and I'm at a
loss for how to prevent this problem.

     Surely this issue had to have been dealt with already in some way,
because
otherwise, even the most rudimentary C programs could not run. I'm probably
doing something wrong. Would someone please point me in the right
direction? :D

Thanks a million,
George Pantazopoulos



--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss



-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss



More information about the Ecos-discuss mailing list