What is __libc_start_main and _start?

让人想犯罪 __ 提交于 2021-02-18 16:58:08

问题


From the past few days I have been trying to understand what happens behind the curtain when we execute a C program. However even after reading numerous posts I cannot find a detailed and accurate explanation for the same. Can someone please help me out ?


回答1:


You would usually find special names like this for specific uses when compiling and linking programs.

Typically, something like _start would be the actual entry point for an executable, it will be located in some object file or library (like crt0.o for the C runtime start-up code) - this would normally be added automagically to your executable file by the linker, similar to the way the C runtime library is added(a).

The operating system code for starting a program would then be akin to (pseudo-code, obviously, and with much less error checking than it should have):

def spawnProg(progName):
    id = newProcess()                       # make process address space
    loadProgram(pid = id, file = progName)  # load program into it
    newThread(pid, initialPc = '_start')    # make new thread to run it

Even though you yourself create a main when coding in C, that's not really where things start happening. There's a whole slew of things that need to be done even before your main program starts. Hence the content of the C start-up code would be along the lines of (at its most simplistic):

_start:  ;; Weave magic here to set up C and libc.

         call __setup_for_c       ; set up C environment
         call __libc_start_main   ; set up standard library
         call _main               ; call your main
         call __libc_stop_main    ; tear down standard library
         call __teardown_for_c    ; tear down C environment
         jmp  __exit              ; return to OS

The "weaving of magic" is whatever it takes to make the environment ready for a C program. This may include things like:

  • setting up static data (this is supposed to be initialised to zeros so it's probably just an allocation of a chunk of of memory, which is then zeroed by the start-up code - otherwise you would need to store a chunk of that size, already zeroed, in the executable file);
  • preparing argc and argv on the stack, and even preparing the stack itself (there are specific calling conventions that may be used for C, and it's likely the operating system doesn't necessarily set up the stack at all when calling _start since the needs of the process are not known);
  • setting up thread-specific data structures (things like random number generators, or error variables, per thread);
  • initialising the C library in other ways; and so on.

Only once all that is complete will it be okay to call your main function. There's also the likelihood that work needs to be done after your main exits, such as:

  • invoking atexit handlers (things you want run automatically on exit, no matter where the exit occurs);
  • detaching from shared resources (for example, shared memory if the OS doesn't do this automatically when it shuts down a process); and
  • freeing up any other resources not automatically cleaned when the process exits, that would otherwise hang around.

(a) Many linkers can be told to not do that if, for example, you're writing something that doesn't use the standard C library, or if you want to provide your own _start routine for low-level work.



来源:https://stackoverflow.com/questions/62709030/what-is-libc-start-main-and-start

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!