blob: 59356b0f0141d270029065154c30e8b6782f3b40 [file] [log] [blame] [edit]
// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/arch/asm.h>
// This defines the entry point in assembly, such that it calls:
//
// extern "C" int64_t TestStart(...);
//
// In the in-process version, that's a tail call so it returns directly to the
// in-process caller. In the separate-process version, the return value is
// passed to _exit.
.function _start, global
// This can assume the sp is already aligned to 16 by the kernel.
#if defined(__aarch64__)
mov x0, sp
#ifdef IN_PROCESS_TEST
b TestStart
#else
bl TestStart
// Return value in x0 is argument.
bl _exit
udf #0
#endif
#elif defined(__riscv)
mv a0, sp
#ifdef IN_PROCESS_TEST
b TestStart
#else
call TestStart
// Return value in a0 is argument.
call _exit
unimp
#endif
#elif defined(__x86_64__)
mov %rsp, %rdi
// If called by ld-startup-tests.cc code, the return address is already in
// the word just below %rsp. If started otherwise, that word will be zero.
// Either way %rsp needs to be adjusted down to 8 mod 16 as a call would do
// by pushing the return address for the C calling convention. Instead of a
// call followed by a trap if it ever did return, just adjust %rsp down and
// jump so that either an original return address or a fault-inducing zero is
// the callee's return address.
sub $8, %rsp
#ifdef IN_PROCESS_TEST
jmp TestStart
#else
call TestStart
// Move the return value into the argument register.
mov %rax, %rdi
call _exit
ud2
#endif
#else
#error "unsupported machine"
#endif
.end_function