Page 1 of 1
How is GCC initialized at program startup?
Posted: Wed May 15, 2013 12:47 pm
by rdos
Most other compilers I've ported have some example crt0 files that could be examined in order to find-out what functions must be called to initialize global variables and similar. Can't find anything about this for GCC, and I'm sure I'm missing something because if I assign a constant string to a static variable, the variable doesn't contain the correct value.
Anybody can give pointers where to find this? I'm using newlib as the C-library.
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 1:07 pm
by jnc100
I'm not sure its the job of crt0 to 'initialize global variables'. Normally, if they're zero then they're in the .bss section and zeroed appropriately, otherwise they are put in the .data section by your compiler. Furthermore, crt0 is normally provided by the C library (rather than the compiler). As an example, the newlib one for linux
here doesn't touch any global variables. Note that for C++, however, you do need to run the constructors of static objects before they are first used (this normally happens at start-up), and the C-library and compiler here need to interact in a way both understand, but I don't think this is your issue here. Is it a linker script issue (e.g. not including a read-only data section)?
Regards,
John.
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 1:52 pm
by rdos
This article provides some insight:
http://gcc.gnu.org/onlinedocs/gccint/In ... ation.html
It seems like the _start() procedure should call a __init() procedure before it calls main. At least if the executable contains .init and .fini sections, which my exeutable seems to contain.
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 1:58 pm
by bluemoon
From your previous post I assume you're porting to x86_64.
If it's not linker issue, other possible place to check is your program loader.
Global variables are relocated using R_X86_64_GLOB_DAT unless you're generating PIC object.
Anyway, this is my crt0.asm for your reference.
I don't touch any global variable here, and I don't think you can automatically reference any global variable here.
Code: Select all
cpu x86-64
bits 64
global _start
extern main, _exit
extern ctor_start, ctor_end, dtor_start, dtor_end
section .data
env dq 0
; ----------------------------------------------
section .text
_start:
xor ebp, ebp
; Constructor & Destructor
; ----------------------------------------------
mov rbx, ctor_start
jmp .ctors_until_end
.call_constructor:
call [rbx]
add rbx,8
.ctors_until_end:
mov rdi, ctor_end
cmp rbx, rdi
jb .call_constructor
mov edi, 0
mov rsi, env
call main
push rax ; save return value
mov rbx, dtor_end
jmp .dtors_until_end
.call_destructor:
sub rbx, 8
call [rbx]
.dtors_until_end:
mov rdi, dtor_start
cmp rbx, rdi
ja .call_destructor
pop rdi ; previously saved return value from main
call _exit
ret
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 2:02 pm
by jnc100
rdos wrote:This article provides some insight:
http://gcc.gnu.org/onlinedocs/gccint/In ... ation.html
It seems like the _start() procedure should call a __init() procedure before it calls main. At least if the executable contains .init and .fini sections, which my exeutable seems to contain.
This only pertains to C++ static objects as far as I can see. It simply provides a more modern way of running the constructors and destructors (as opposed to using __CTOR_LIST__ and __DTOR_LIST__). I presume you need to decide for your platform whether you go down this route (in which case your newlib crt0 __start should call __init before main and __fini afterwards, and presumably provide some magic in crtstuff.c in gcc) or traverse the __CTOR_LIST__ items yourself.
Regards,
John.
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 2:07 pm
by sortie
Be sure to read the wiki. I documented crt*.o in the Creating a C Library article.
http://wiki.osdev.org/Creating_a_C_Libr ... ialization
Re: How is GCC initialized at program startup?
Posted: Wed May 15, 2013 2:30 pm
by rdos
Thanks, sortie. That's the information I needed.
My hypothesis is that by specifying extra parts as crtbegin.o crtend.o crti.o crtn.o will generate all that is needed in order to call _init and _fini.