Compiler and linker interaction for producing main

How does the compiler (I'm of course talking about gcc, but this should be valid for any compiler availible) tell the linker to put main in the start?

Does the linker do that by it self?

As far as I've understod it it's like this:
The compiler puts compiled programs into object files and then tells the linker to link them all. The main func is somewhere in there, and isn't specificly placed at the start, but instead called by _start, which I have no idea where it comes from, or where it's placed.

Happy coding wishes
the one and only
[b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]

Comments

  • : How does the compiler (I'm of course talking about gcc, but this should be valid for any compiler availible) tell the linker to put main in the start?
    :
    : Does the linker do that by it self?
    :
    : As far as I've understod it it's like this:
    : The compiler puts compiled programs into object files and then tells the linker to link them all. The main func is somewhere in there, and isn't specificly placed at the start, but instead called by _start, which I have no idea where it comes from, or where it's placed.
    :
    : Happy coding wishes
    : the one and only
    : [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    :
    [blue]
    The way its done is system dependent. On Windows, kernel32.dll
    executes a programs [b]mainCRTstartup()[/b] routine.

    mainCRTstartup() is the first routine executed. It is generated
    by the compilier. mainCRTstartup() executes all global constructers,
    and catches all uncaught exceptions.

    mainCRTstartup() then calls the main() routine. The linker
    loads main() at a specific address. Most linkers allow you
    to specify another starting point (Besides _main). Some linkers
    also allow you to specify the loading address (Like the ld linker in
    GCC)

    For an example, in my OS, I have my linker load _main() at absolute
    address 0x1000:0. We do a simple [b]jmp[/b] to that address to
    execute it.

    btw, the CRT in mainCRTstartup() = C Run Time
    [/blue]
  • : : How does the compiler (I'm of course talking about gcc, but this should be valid for any compiler availible) tell the linker to put main in the start?
    : :
    : : Does the linker do that by it self?
    : :
    : : As far as I've understod it it's like this:
    : : The compiler puts compiled programs into object files and then tells the linker to link them all. The main func is somewhere in there, and isn't specificly placed at the start, but instead called by _start, which I have no idea where it comes from, or where it's placed.
    : :
    : : Happy coding wishes
    : : the one and only
    : : [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    : :
    : [blue]
    : The way its done is system dependent. On Windows, kernel32.dll
    : executes a programs [b]mainCRTstartup()[/b] routine.
    :
    : mainCRTstartup() is the first routine executed. It is generated
    : by the compilier. mainCRTstartup() executes all global constructers,
    : and catches all uncaught exceptions.
    :
    : mainCRTstartup() then calls the main() routine. The linker
    : loads main() at a specific address. Most linkers allow you
    : to specify another starting point (Besides _main). Some linkers
    : also allow you to specify the loading address (Like the ld linker in
    : GCC)
    :
    : For an example, in my OS, I have my linker load _main() at absolute
    : address 0x1000:0. We do a simple [b]jmp[/b] to that address to
    : execute it.
    :
    : btw, the CRT in mainCRTstartup() = C Run Time
    : [/blue]
    :

    Is mainCRTstartup() in kernel32?
    And the linker puts main at a specific address. How does the compiler tell the linker where to find main?
    Does the linker simply search for main, and then put it in front (or at whatever address needed)?
  • [b][red]This message was edited by MT2002 at 2007-3-14 15:59:40[/red][/b][hr]

    : : : How does the compiler (I'm of course talking about gcc, but this should be valid for any compiler availible) tell the linker to put main in the start?
    : : :
    : : : Does the linker do that by it self?
    : : :
    : : : As far as I've understod it it's like this:
    : : : The compiler puts compiled programs into object files and then tells the linker to link them all. The main func is somewhere in there, and isn't specificly placed at the start, but instead called by _start, which I have no idea where it comes from, or where it's placed.
    : : :
    : : : Happy coding wishes
    : : : the one and only
    : : : [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    : : :
    : : [blue]
    : : The way its done is system dependent. On Windows, kernel32.dll
    : : executes a programs [b]mainCRTstartup()[/b] routine.
    : :
    : : mainCRTstartup() is the first routine executed. It is generated
    : : by the compilier. mainCRTstartup() executes all global constructers,
    : : and catches all uncaught exceptions.
    : :
    : : mainCRTstartup() then calls the main() routine. The linker
    : : loads main() at a specific address. Most linkers allow you
    : : to specify another starting point (Besides _main). Some linkers
    : : also allow you to specify the loading address (Like the ld linker in
    : : GCC)
    : :
    : : For an example, in my OS, I have my linker load _main() at absolute
    : : address 0x1000:0. We do a simple [b]jmp[/b] to that address to
    : : execute it.
    : :
    : : btw, the CRT in mainCRTstartup() = C Run Time
    : : [/blue]
    : :
    :
    : Is mainCRTstartup() in kernel32?
    [blue]
    No. mainCRTstartup() is [b]generated[/b] by the compilier.
    The OS does not know about global objects in C, because everything
    is global.

    Only the compilier is able to determin the differences between 'local'
    and 'global' objects. Hence, only the compilier knows what constructers
    to call. Alas, the compilier generates mainCRTstartup()
    [/blue]
    : And the linker puts main at a specific address. How does the compiler tell the linker where to find main?
    [blue]
    This is to my understanding (I could be incorrect here):

    The compilier does not generate the machine code directly. It compiles
    the source into object code. There are many object code formats (ELF,
    COFF, etc). Object code contains machine instructions, as well as
    symbolic names. It could also include debugging information.

    It is the linker that specifies the offset addresses of the symbols.

    In this case, the symbolic name for main() is useally [b]_main[/b].
    When the linker searches through the object files, and determins
    what address the entry point is to be loaded at. It loads [b]_main[/b]
    (from the object code) into the specified address into the final
    program.

    The way it does this depends on the memory map used for linking.
    An example memory map could be (For GDD ld linker):[/blue][code]
    .data
    +All global varable objects, and static object symbols
    are loaded here
    .rodata
    +512 bytes - read only data.
    For example, printf("Hi") - The string 'Hi' will be here.
    Note: Not all linkers use this section
    .bss
    +Lay 1024 bytes for stack
    .code
    +_mainCRTstartup, _main, sometimes _WinMain (For Win32 apps)
    +Other routines..
    [/code][blue]
    In Win32 PE Executables, _mainCRTstartup (the symbol) is loaded at the
    beginning address by the linker. _main() *could be* (Doesnt have to be)
    loaded right after _mainCRTstartup.
    [/blue]
    : Does the linker simply search for main, and then put it in front (or at whatever address needed)?
    [blue]
    Thats it :) The linker looks through the object code for the symbol
    _main, and loads it into the executable at the starting address.


    The *Exact* details on everything depends on the object format you use,
    and your development envirement, and target platform. Also,
    mainCRTstartup() is system dependent. ie, not all platforms use it.

    (Another example with my OS - I do an explicate jmp directly to _main.
    I do not have any special "in between" routine like mainCRTstartup().
    Of course, Im using C to avoid the problems with setting up with C++)

    This is my understanding of it.[/blue]
  • : [b][red]This message was edited by MT2002 at 2007-3-14 15:59:40[/red][/b][hr]
    :
    : : : : How does the compiler (I'm of course talking about gcc, but this should be valid for any compiler availible) tell the linker to put main in the start?
    : : : :
    : : : : Does the linker do that by it self?
    : : : :
    : : : : As far as I've understod it it's like this:
    : : : : The compiler puts compiled programs into object files and then tells the linker to link them all. The main func is somewhere in there, and isn't specificly placed at the start, but instead called by _start, which I have no idea where it comes from, or where it's placed.
    : : : :
    : : : : Happy coding wishes
    : : : : the one and only
    : : : : [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    : : : :
    : : : [blue]
    : : : The way its done is system dependent. On Windows, kernel32.dll
    : : : executes a programs [b]mainCRTstartup()[/b] routine.
    : : :
    : : : mainCRTstartup() is the first routine executed. It is generated
    : : : by the compilier. mainCRTstartup() executes all global constructers,
    : : : and catches all uncaught exceptions.
    : : :
    : : : mainCRTstartup() then calls the main() routine. The linker
    : : : loads main() at a specific address. Most linkers allow you
    : : : to specify another starting point (Besides _main). Some linkers
    : : : also allow you to specify the loading address (Like the ld linker in
    : : : GCC)
    : : :
    : : : For an example, in my OS, I have my linker load _main() at absolute
    : : : address 0x1000:0. We do a simple [b]jmp[/b] to that address to
    : : : execute it.
    : : :
    : : : btw, the CRT in mainCRTstartup() = C Run Time
    : : : [/blue]
    : : :
    : :
    : : Is mainCRTstartup() in kernel32?
    : [blue]
    : No. mainCRTstartup() is [b]generated[/b] by the compilier.
    : The OS does not know about global objects in C, because everything
    : is global.
    :
    : Only the compilier is able to determin the differences between 'local'
    : and 'global' objects. Hence, only the compilier knows what constructers
    : to call. Alas, the compilier generates mainCRTstartup()
    : [/blue]
    : : And the linker puts main at a specific address. How does the compiler tell the linker where to find main?
    : [blue]
    : This is to my understanding (I could be incorrect here):
    :
    : The compilier does not generate the machine code directly. It compiles
    : the source into object code. There are many object code formats (ELF,
    : COFF, etc). Object code contains machine instructions, as well as
    : symbolic names. It could also include debugging information.
    :
    : It is the linker that specifies the offset addresses of the symbols.
    :
    : In this case, the symbolic name for main() is useally [b]_main[/b].
    : When the linker searches through the object files, and determins
    : what address the entry point is to be loaded at. It loads [b]_main[/b]
    : (from the object code) into the specified address into the final
    : program.
    :
    : The way it does this depends on the memory map used for linking.
    : An example memory map could be (For GDD ld linker):[/blue][code]
    : .data
    : +All global varable objects, and static object symbols
    : are loaded here
    : .rodata
    : +512 bytes - read only data.
    : For example, printf("Hi") - The string 'Hi' will be here.
    : Note: Not all linkers use this section
    : .bss
    : +Lay 1024 bytes for stack
    : .code
    : +_mainCRTstartup, _main, sometimes _WinMain (For Win32 apps)
    : +Other routines..
    : [/code][blue]
    : In Win32 PE Executables, _mainCRTstartup (the symbol) is loaded at the
    : beginning address by the linker. _main() *could be* (Doesnt have to be)
    : loaded right after _mainCRTstartup.
    : [/blue]
    : : Does the linker simply search for main, and then put it in front (or at whatever address needed)?
    : [blue]
    : Thats it :) The linker looks through the object code for the symbol
    : _main, and loads it into the executable at the starting address.
    :
    :
    : The *Exact* details on everything depends on the object format you use,
    : and your development envirement, and target platform. Also,
    : mainCRTstartup() is system dependent. ie, not all platforms use it.
    :
    : (Another example with my OS - I do an explicate jmp directly to _main.
    : I do not have any special "in between" routine like mainCRTstartup().
    : Of course, Im using C to avoid the problems with setting up with C++)
    :
    : This is my understanding of it.[/blue]
    :


    The way you describe is pretty much how it works on any kind of system.

    Note that C has the same setup problems as C++, just no contructors to tend to. Every global/static variable that you initialize must be set before main() is called.
  • : : :
    : : : Is mainCRTstartup() in kernel32?
    : : [blue]
    : : No. mainCRTstartup() is [b]generated[/b] by the compilier.
    : : The OS does not know about global objects in C, because everything
    : : is global.
    : :
    : : Only the compilier is able to determin the differences between 'local'
    : : and 'global' objects. Hence, only the compilier knows what constructers
    : : to call. Alas, the compilier generates mainCRTstartup()
    : : [/blue]
    : : : And the linker puts main at a specific address. How does the compiler tell the linker where to find main?
    : : [blue]
    : : This is to my understanding (I could be incorrect here):
    : :
    : : The compilier does not generate the machine code directly. It compiles
    : : the source into object code. There are many object code formats (ELF,
    : : COFF, etc). Object code contains machine instructions, as well as
    : : symbolic names. It could also include debugging information.
    : :
    : : It is the linker that specifies the offset addresses of the symbols.
    : :
    : : In this case, the symbolic name for main() is useally [b]_main[/b].
    : : When the linker searches through the object files, and determins
    : : what address the entry point is to be loaded at. It loads [b]_main[/b]
    : : (from the object code) into the specified address into the final
    : : program.
    : :
    : : The way it does this depends on the memory map used for linking.
    : : An example memory map could be (For GDD ld linker):[/blue][code]
    : : .data
    : : +All global varable objects, and static object symbols
    : : are loaded here
    : : .rodata
    : : +512 bytes - read only data.
    : : For example, printf("Hi") - The string 'Hi' will be here.
    : : Note: Not all linkers use this section
    : : .bss
    : : +Lay 1024 bytes for stack
    : : .code
    : : +_mainCRTstartup, _main, sometimes _WinMain (For Win32 apps)
    : : +Other routines..
    : : [/code][blue]
    : : In Win32 PE Executables, _mainCRTstartup (the symbol) is loaded at the
    : : beginning address by the linker. _main() *could be* (Doesnt have to be)
    : : loaded right after _mainCRTstartup.
    : : [/blue]
    : : : Does the linker simply search for main, and then put it in front (or at whatever address needed)?
    : : [blue]
    : : Thats it :) The linker looks through the object code for the symbol
    : : _main, and loads it into the executable at the starting address.
    : :
    : :
    : : The *Exact* details on everything depends on the object format you use,
    : : and your development envirement, and target platform. Also,
    : : mainCRTstartup() is system dependent. ie, not all platforms use it.
    : :
    : : (Another example with my OS - I do an explicate jmp directly to _main.
    : : I do not have any special "in between" routine like mainCRTstartup().
    : : Of course, Im using C to avoid the problems with setting up with C++)
    : :
    : : This is my understanding of it.[/blue]
    : :
    :
    :
    : The way you describe is pretty much how it works on any kind of system.
    :
    : Note that C has the same setup problems as C++, just no contructors to tend to. Every global/static variable that you initialize must be set before main() is called.
    :

    Thanks a lot!
    Now I understand.


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories