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