60 lines · cpp
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10// REQUIRES: target={{aarch64-.+}}11// UNSUPPORTED: target={{.*-windows.*}}12 13// Basic test for float registers number are accepted.14 15#include <stdlib.h>16#include <string.h>17#include <unwind.h>18 19// Using __attribute__((section("main_func"))) is ELF specific, but then20// this entire test is marked as requiring Linux, so we should be good.21//22// We don't use dladdr() because on musl it's a no-op when statically linked.23extern char __start_main_func;24extern char __stop_main_func;25 26_Unwind_Reason_Code frame_handler(struct _Unwind_Context *ctx, void *arg) {27 (void)arg;28 29 // Unwind until the main is reached, above frames depend on the platform and30 // architecture.31 uintptr_t ip = _Unwind_GetIP(ctx);32 if (ip >= (uintptr_t)&__start_main_func &&33 ip < (uintptr_t)&__stop_main_func) {34 _Exit(0);35 }36 37 return _URC_NO_REASON;38}39 40__attribute__((noinline)) void foo() {41 // Provide some CFI directives that instructs the unwinder where given42 // float register is.43#if defined(__aarch64__)44 // DWARF register number for V0-V31 registers are 64-95.45 // Previous value of V0 is saved at offset 0 from CFA.46 asm volatile(".cfi_offset 64, 0");47 // From now on the previous value of register can't be restored anymore.48 asm volatile(".cfi_undefined 65");49 asm volatile(".cfi_undefined 95");50 // Previous value of V2 is in V30.51 asm volatile(".cfi_register 66, 94");52#endif53 _Unwind_Backtrace(frame_handler, NULL);54}55 56__attribute__((section("main_func"))) int main(int, char **) {57 foo();58 return -2;59}60