xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Linux/SingleStepCheck.h (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick //===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===//
2*061da546Spatrick //
3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*061da546Spatrick //
7*061da546Spatrick //===----------------------------------------------------------------------===//
8*061da546Spatrick 
9*061da546Spatrick #ifndef liblldb_SingleStepCheck_H_
10*061da546Spatrick #define liblldb_SingleStepCheck_H_
11*061da546Spatrick 
12*061da546Spatrick #include <memory>
13*061da546Spatrick #include <sched.h>
14*061da546Spatrick #include <sys/types.h>
15*061da546Spatrick 
16*061da546Spatrick namespace lldb_private {
17*061da546Spatrick namespace process_linux {
18*061da546Spatrick 
19*061da546Spatrick // arm64 linux had a bug which prevented single-stepping and watchpoints from
20*061da546Spatrick // working on non-boot cpus, due to them being incorrectly initialized after
21*061da546Spatrick // coming out of suspend.  This issue is particularly affecting android M, which
22*061da546Spatrick // uses suspend ("doze mode") quite aggressively. This code detects that
23*061da546Spatrick // situation and makes single-stepping work by doing all the step operations on
24*061da546Spatrick // the boot cpu.
25*061da546Spatrick //
26*061da546Spatrick // The underlying issue has been fixed in android N and linux 4.4. This code can
27*061da546Spatrick // be removed once these systems become obsolete.
28*061da546Spatrick 
29*061da546Spatrick #if defined(__arm64__) || defined(__aarch64__)
30*061da546Spatrick class SingleStepWorkaround {
31*061da546Spatrick   ::pid_t m_tid;
32*061da546Spatrick   cpu_set_t m_original_set;
33*061da546Spatrick 
34*061da546Spatrick   SingleStepWorkaround(const SingleStepWorkaround &) = delete;
35*061da546Spatrick   void operator=(const SingleStepWorkaround &) = delete;
36*061da546Spatrick 
37*061da546Spatrick public:
SingleStepWorkaround(::pid_t tid,cpu_set_t original_set)38*061da546Spatrick   SingleStepWorkaround(::pid_t tid, cpu_set_t original_set)
39*061da546Spatrick       : m_tid(tid), m_original_set(original_set) {}
40*061da546Spatrick   ~SingleStepWorkaround();
41*061da546Spatrick 
42*061da546Spatrick   static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid);
43*061da546Spatrick };
44*061da546Spatrick #else
45*061da546Spatrick class SingleStepWorkaround {
46*061da546Spatrick public:
47*061da546Spatrick   static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid) {
48*061da546Spatrick     return nullptr;
49*061da546Spatrick   }
50*061da546Spatrick };
51*061da546Spatrick #endif
52*061da546Spatrick 
53*061da546Spatrick } // end namespace process_linux
54*061da546Spatrick } // end namespace lldb_private
55*061da546Spatrick 
56*061da546Spatrick #endif // #ifndef liblldb_SingleStepCheck_H_
57