================ @@ -0,0 +1,127 @@ +//===--- RunOnNewStack.cpp - Crash Recovery -------------------------------===// +// +// 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 "llvm/Support/ProgramStack.h" +#include "llvm/Config/config.h" +#include "llvm/Support/Compiler.h" + +#ifdef LLVM_ON_UNIX +# include <sys/resource.h> // for getrlimit +#endif + +#ifdef _MSC_VER +# include <intrin.h> // for _AddressOfReturnAddress +#endif + +#ifndef LLVM_HAS_SPLIT_STACKS +# include "llvm/Support/thread.h" +#endif + +using namespace llvm; + +uintptr_t llvm::getStackPointer() { +#if __GNUC__ || __has_builtin(__builtin_frame_address) + return (uintptr_t)__builtin_frame_address(0); +#elif defined(_MSC_VER) + return (uintptr_t)_AddressOfReturnAddress(); +#else + volatile char CharOnStack = 0; + // The volatile store here is intended to escape the local variable, to + // prevent the compiler from optimizing CharOnStack into anything other + // than a char on the stack. + // + // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19. + char *volatile Ptr = &CharOnStack; + return (uintptr_t)Ptr; +#endif +} + +unsigned llvm::getDefaultStackSize() { +#ifdef LLVM_ON_UNIX + rlimit RL; + getrlimit(RLIMIT_STACK, &RL); + return RL.rlim_cur; +#else + // Clang recursively parses, instantiates templates, and evaluates constant + // expressions. We've found 8MiB to be a reasonable stack size given the way + // Clang works and the way C++ is commonly written. + return 8 << 20; +#endif +} + +// Not an anonymous namespace to avoid warning about undefined local function. +namespace llvm { +#ifdef LLVM_HAS_SPLIT_STACKS_AARCH64 +void runOnNewStackImpl(void *Stack, void (*Fn)(void *), void *Ctx) __asm__( + "_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_"); + +// This can't use naked functions because there is no way to know if cfi +// directives are being emitted or not. +// +// When adding new platforms it may be better to move to a .S file with macros +// for dealing with platform differences. +__asm__ ( + ".globl _ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_\n\t" + ".p2align 2\n\t" + "_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_:\n\t" + ".cfi_startproc\n\t" + "mov x16, sp\n\t" + "sub x0, x0, #0x20\n\t" // subtract space from stack + "stp xzr, x16, [x0, #0x00]\n\t" // save old sp + "stp x29, x30, [x0, #0x10]\n\t" // save fp, lr + "mov sp, x0\n\t" // switch to new stack + "add x29, x0, #0x10\n\t" // switch to new frame + ".cfi_def_cfa w29, 16\n\t" ---------------- rnk wrote:
Shouldn't these appear immediately after the stack switch, since as soon as you update SP, the values from the parent frame can no longer be recovered? This will fix stack unwinding when single-stepping through this code. https://github.com/llvm/llvm-project/pull/136046 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits