Files
clang-p2996/libc/startup/linux/aarch64/start.cpp
Schrodinger ZHU Yifan 2bc994456c [libc] major refactor of startup library (#76092)
* separate initialization routines into _start and do_start for all
architectures.
* lift do_start as a separate object library to avoid code duplication.
* (addtionally) address the problem of building hermetic libc with
-fstack-pointer-*

The `crt1.o` is now a merged result of three components:

```
___
  |___ x86_64
  |      |_______ start.cpp.o    <- _start (loads process initial stack and aligns stack pointer)
  |      |_______ tls.cpp.o      <- init_tls, cleanup_tls, set_thread_pointer (TLS related routines) 
  |___ do_start.cpp.o            <- do_start (sets up global variables and invokes the main function) 
```
2024-01-04 12:51:14 -08:00

25 lines
1.3 KiB
C++

//===-- Implementation of _start for aarch64 ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "startup/linux/do_start.h"
extern "C" [[noreturn]] void _start() {
// Skip the Frame Pointer and the Link Register
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst
// Section 6.2.3. Note that this only works if the current function
// is not using any callee-saved registers (x19 to x28). If the
// function uses such registers, then their value is pushed on to the
// stack before the frame pointer an link register values. That breaks
// the assumption that stepping over the frame pointer and link register
// will take us to the previous stack pointer. That is the reason why the
// actual business logic of the startup code is pushed into a non-inline
// function do_start so that this function is free of any stack usage.
LIBC_NAMESPACE::app.args = reinterpret_cast<LIBC_NAMESPACE::Args *>(
reinterpret_cast<uintptr_t *>(__builtin_frame_address(0)) + 2);
LIBC_NAMESPACE::do_start();
}