Still need (desperately!!!) help with initializing code

gregory.menke at gsfc.nasa.gov gregory.menke at gsfc.nasa.gov
Wed Nov 26 16:52:03 UTC 2003


Leon Pollak writes:
 > Gregory,
 > 	I have crtbegin.o   crtbeginT.o  ecrti.o  ncrtn.o crtbeginS.o  ecrtn.o 
 > ncrti.o files in gcc/860 directory.
 > 
 > 	Function _ini resides only in ecrt.o and ncrti.o and contains:
 > 
 > ecrti.o:     file format elf32-powerpc
 > Disassembly of section .text:
 > Disassembly of section .init:
 > 00000000 <__init>:
 >    0:   94 21 ff f0     stwu    r1,-16(r1)
 >    4:   7c 08 02 a6     mflr    r0
 >    8:   90 01 00 14     stw     r0,20(r1)
 > Disassembly of section .fini:
 > 00000000 <__fini>:
 >    0:   94 21 ff f0     stwu    r1,-16(r1)
 >    4:   7c 08 02 a6     mflr    r0
 >    8:   90 01 00 14     stw     r0,20(r1)
 > 
 > 
 > ncrti.o:     file format elf32-powerpc
 > Disassembly of section .text:
 > Disassembly of section .init:
 > 00000000 <_init>:
 >    0:   94 21 ff f0     stwu    r1,-16(r1)
 >    4:   7c 08 02 a6     mflr    r0
 >    8:   93 e1 00 0c     stw     r31,12(r1)
 >    c:   90 01 00 10     stw     r0,16(r1)
 >   10:   4b ff ff fd     bl      c <_init+0xc>
 >   14:   7f e8 02 a6     mflr    r31
 > Disassembly of section .fini:
 > 00000000 <_fini>:
 >    0:   94 21 ff f0     stwu    r1,-16(r1)
 >    4:   7c 08 02 a6     mflr    r0
 >    8:   93 e1 00 0c     stw     r31,12(r1)
 >    c:   90 01 00 10     stw     r0,16(r1)
 >   10:   4b ff ff fd     bl      c <_fini+0xc>
 >   14:   7f e8 02 a6     mflr    r31

The files are not all required, some do different things for different
environments.  Similarly, ld supplies a number of different default
link scripts.

The files supply the prolog and epilog of the _init and _fini
functions, the constructor/destructor code from your compiled
application software supplies the content.
 
 > 	Can you point out which one of them is suitable? And what about all these 
 > ctr*.o? What are they for?

I think you need ecrti.o, crtbegin.o, then your application .o files,
then rtems .a files, then crtend.o and ecrtn.o.  Much of this
statement is based on trial and error, using objdump against the
linked executable to see when things work.  I'm not gcc-aware enough
to give good reasons.

The following are extracts from an objdump of a C++ test program I
compile for the MCP750 & MTX603.  The program has several C++ objects
w/ constructors, one of which is global, initialized via the code
shown;

0000301c <_init>:
    301c:       94 21 ff f0     stwu    r1,-16(r1)
    3020:       7c 08 02 a6     mflr    r0
    3024:       90 01 00 14     stw     r0,20(r1)
    3028:       48 00 00 e1     bl      3108 <frame_dummy>
    302c:       48 06 0b 71     bl      63b9c <__do_global_ctors_aux>
    3030:       80 01 00 14     lwz     r0,20(r1)
    3034:       7c 08 03 a6     mtlr    r0
    3038:       38 21 00 10     addi    r1,r1,16
    303c:       4e 80 00 20     blr
Disassembly of section .text:

...

00063b9c <__do_global_ctors_aux>:
   63b9c:       94 21 ff e0     stwu    r1,-32(r1)
   63ba0:       7c 08 02 a6     mflr    r0
   63ba4:       48 00 00 05     bl      63ba8 <__do_global_ctors_aux+0xc>
   63ba8:       93 c1 00 18     stw     r30,24(r1)
   63bac:       7f c8 02 a6     mflr    r30
   63bb0:       90 01 00 24     stw     r0,36(r1)
   63bb4:       80 1e ff f0     lwz     r0,-16(r30)
   63bb8:       93 e1 00 1c     stw     r31,28(r1)
   63bbc:       7f c0 f2 14     add     r30,r0,r30
   63bc0:       81 3e 80 00     lwz     r9,-32768(r30)
   63bc4:       80 09 ff fc     lwz     r0,-4(r9)
   63bc8:       3b e9 ff fc     addi    r31,r9,-4
   63bcc:       2c 00 ff ff     cmpwi   r0,-1
   63bd0:       41 82 00 18     beq-    63be8 <__do_global_ctors_aux+0x4c>
   63bd4:       7c 08 03 a6     mtlr    r0
   63bd8:       4e 80 00 21     blrl
   63bdc:       84 1f ff fc     lwzu    r0,-4(r31)
   63be0:       2c 00 ff ff     cmpwi   r0,-1
   63be4:       40 82 ff f0     bne+    63bd4 <__do_global_ctors_aux+0x38>
   63be8:       80 01 00 24     lwz     r0,36(r1)
   63bec:       83 c1 00 18     lwz     r30,24(r1)
   63bf0:       83 e1 00 1c     lwz     r31,28(r1)
   63bf4:       7c 08 03 a6     mtlr    r0
   63bf8:       38 21 00 20     addi    r1,r1,32
   63bfc:       4e 80 00 20     blr


As you can see there is a lot going on, and there is a similar
arrangement for destructors.  All I supplied in bspspecs was the
various ecrt & crt .o files, and the .init and .fini sections in the
linkcmds.  Your objdumps show _init is not fully formed, hence it does
nothing.  An interesting thing about my dumps above is _init is in
.init, while the global_ctors business is all in .text- this is one
reason why .init and .fini should always follow .text around.

If you do get the .o files right but still have linkcmd problems, you
may find the app starts crashing at init-time.  The constructors must
be laid out as an array of function pointers which the global_ctors
code can traverse, the .ctors and .dtors sections control that.


 > 	You write that they (who?) must be positioned in the right order for linker, 
 > but what order is right? 

see above.

>May be I can read about this instead of bombarding 
 > mail list with such questions?

I wish I knew.  I suspect documentation of this sort of thing exists,
but in a form sufficiently technical that you have to understand the
issue before you can understand the documentation.  It also may be
located deep inside the gcc development crowd.  


 > ------------------------------------------------------------------------------------------------------------
 >  About copying rom->ram. I thought that only .data section ,ust be copied, but 
 > you wrote:
 > 	From the standpoint of copying from rom to ram, the init,fini code is
 > 	usually copied right along with .text.
 > Does this mean that also sections .init and .fini must be copied?
 > 

Yes.  Their sections will usually be located right next to .text.
Mostly it depends on how fancy the linkscript is- but they do need to
be copied because _init and _fini related sections contain code.

OTOH, if a bsp does not copy .text (maybe its running from ROM), then
.init,.fini also are not copied- they always follow .text.  In this
case, the only sections to be copied would be the .data family.

Remember, there are 2 potential address ranges.  First, the runtime
addresses of code & data, assigned by the linker at link-time- this is
where code & data must be for the program to run.  If the program is
not there at run-time, it must be copied there from wherever it is-
this is where the 2nd address range comes in.  A bsp that copies
sections must be aware of both address ranges, specifically, the
relocation code must know it.  Its job is to copy the image & zero
.bss.  The linker has already arranged the image as a contiguous chunk
of bytes, .text, then .data with .bss stripped out.  The relocator
just copies the image.  Since .bss exists after .data, the relocator
doesn't have to be smart- it copies the image, zeros .bss and jumps to
the init code- which is usually the first part of .text.  .init and
.fini are arranged to be alongside .text, so they are carried along
with it.  There are a number of other sections treated this way.
linker symbols are used to identify the various parts of the image so
the relocation addresses are not hardcoded.

If .data is the only section being copied, then the linkscript must
have been arranged so .text links to its location in ROM, and .data
links to its run-time addresses in RAM.  The relocation code must then
only copy .data into ram- but the idea is the same.

Gregm




More information about the users mailing list