blob: 4b2db95a30350e95f161b9b3da2b77c7a1f26483 [file] [log] [blame]
// Copyright 2024 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 "backtrace.h"
#include <lib/arch/asm.h>
#include "test-start.h"
[[gnu::visibility("hidden")]] extern arch::AsmLabel _start, _start_end;
extern "C" [[gnu::noinline]] int64_t TestStart() {
const uintptr_t ra = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
const FramePointer* fp = FramePointer::Get();
// The immediate caller is _start, which pushed its own frame pointer.
if (fp->ra != ra) {
return 1;
}
if (fp->fp == nullptr) {
return 2;
}
const uintptr_t start = arch::kAsmLabelAddress<_start>;
const uintptr_t end = arch::kAsmLabelAddress<_start_end>;
if (ra <= start) {
return 3;
}
if (ra > end) {
return 4;
}
// _start is the root of the call graph, so its "caller's" return address and
// frame pointer should both be zero.
fp = fp->Next();
if (fp->ra != 0) {
return 4;
}
if (fp->fp != nullptr) {
return 5;
}
return 17;
}