David Spickett 9db2541d4c [lldb][AArch64] Add UnwindPlan for Linux sigreturn
This adds a specific unwind plan for AArch64 Linux sigreturn frames.
Previously we assumed that the fp would be valid here but it is not.

https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S

On Ubuntu Bionic it happened to point to an old frame info which meant
you got what looked like a correct backtrace. On Focal, the info is
completely invalid. (probably due to some code shuffling in libc)

This adds an UnwindPlan that knows that the sp in a sigreturn frame
points to an rt_sigframe from which we can offset to get saved
sp and pc values to backtrace correctly.

Based on LibUnwind's change: https://reviews.llvm.org/D90898

A new test is added that sets all compares the frames from the initial
signal catch to the handler break. Ensuring that the stack/frame pointer,
function name and register values match.
(this test is AArch64 Linux specific because it's the only one
with a specific unwind plan for this situation)

Fixes https://bugs.llvm.org/show_bug.cgi?id=52165

Reviewed By: omjavaid, labath

Differential Revision: https://reviews.llvm.org/D112069
2021-11-11 11:32:06 +00:00

66 lines
2.1 KiB
C++

//===-- PlatformLinux.h -----------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H
#define LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H
#include "Plugins/Platform/POSIX/PlatformPOSIX.h"
namespace lldb_private {
namespace platform_linux {
class PlatformLinux : public PlatformPOSIX {
public:
PlatformLinux(bool is_host);
static void Initialize();
static void Terminate();
// lldb_private::PluginInterface functions
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
static llvm::StringRef GetPluginNameStatic(bool is_host) {
return is_host ? Platform::GetHostPlatformName() : "remote-linux";
}
static llvm::StringRef GetPluginDescriptionStatic(bool is_host);
llvm::StringRef GetPluginName() override {
return GetPluginNameStatic(IsHost());
}
// lldb_private::Platform functions
llvm::StringRef GetDescription() override {
return GetPluginDescriptionStatic(IsHost());
}
void GetStatus(Stream &strm) override;
bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override;
uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override;
bool CanDebugProcess() override;
void CalculateTrapHandlerSymbolNames() override;
lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const llvm::Triple &triple,
ConstString name) override;
MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr,
lldb::addr_t length, unsigned prot,
unsigned flags, lldb::addr_t fd,
lldb::addr_t offset) override;
};
} // namespace platform_linux
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PLATFORM_LINUX_PLATFORMLINUX_H