Sep 17, 2022

[elf][note] entry function

ELF executable entry function

_start function facts


_start function implements

  1. Early low-level initialization, such as
    1. Configuring processor registers
    2. Initializing external memory
    3. Enabling caches
    4. Configuring the MMU
  2. Stack initialization, making sure that the stack is properly aligned per the ABI requirements
  3. Frame pointer initialization
  4. Initialization of the C/C++ runtime
    Relocate any relocatable sections (if not handled by the loader or linker)
    1. Initializing global and static memory
    2. Runtime initializes a subset of uninitialized memory (no = in the declaration) to 0.
      This includes global and static variables, but not stack variables. All uninitialized data that needs to be set to 0 is placed into the .bss section of the compiled program image by the linker. The location of the .bss section is identified during initialization, and the memory is typically set to 0 with memset.
    3. C++ global objects must be constructed before calling main. The linker places these constructors into the .init, .init_array, or .ctors section of the image.
      Some compilers also allow C and C++ functions to be marked as a constructor using a compiler attribute (e.g., __attribute__((constuctor))). The constructors are stored in a list by the linker.
      The runtime initialization process iterates through the list and calls each constructor.
    4. Prepare the argc and argv variables for invoking main (even if it’s just setting these to 0/NULL)
    5. Perform any additional setup steps required by the C/C++ standard library implementation.
      These additional runtime initialization steps are run for many programs (but not all):
      1. Heap initialization
      2. Initialize stdio (i.e., stdin, stdout, stderr)
      3. Initialize exception support (if using C++)
      4. Register destructors and other cleanup functions that will run when exiting the program (using atexit and __cxa_atexit)
      5. Assembly files commonly found during this portion of the startup process are crtbegin.s, crtend.s, crti.s, and crtn.s.
      6. Prepare environment variables
  5. Initialization of other scaffolding required by the system
      Program scaffolding setup before main might include:
      1. Threading support and thread local storage
      2. Buffer overrun detection
      3. Stack logging
      4. Run-time error checks
      5. Locale settings
      6. Math error handling
      7. Default math library precision
  6. Jumping to main
  7. Exiting the program with the return code from main

So, how do we get to the _start?

  • Baremetal: Reset Vector
  • Bootloader Launches Application
  • OS Calls an exec function
    Loaders will often perform the following actions:
    • Check permissions
    • Allocate space for the program’s stack
    • Allocate space for the program’s heap
    • Initialize registers (e.g., stack pointer)
    • Push argc, argv, and envp onto the program stack
    • Map virtual address spaces
    • Dynamic linking
    • Relocations
    • Call pre-initialization functions

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.