1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_KALLSYMS_LAZY_KERNEL_SYMBOLIZER_H_
18 #define SRC_KALLSYMS_LAZY_KERNEL_SYMBOLIZER_H_
19 
20 #include <memory>
21 
22 #include "perfetto/ext/base/thread_checker.h"
23 
24 namespace perfetto {
25 
26 class KernelSymbolMap;
27 
28 // This class is a wrapper around KernelSymbolMap. It serves two purposes:
29 // 1. Deals with /proc/kallsyms reads and temporary lowering of kptr_restrict.
30 //    KernelSymbolMap is just a parser and doesn't do I/O.
31 // 2. Allows to share the same KernelSymbolMap instance across several clients
32 //    and tear it down when tracing stops.
33 //
34 // LazyKernelSymbolizer is owned by the (one) FtraceController. FtraceController
35 // handles LazyKernelSymbolizer pointers to  N CpuReader-s (one per CPU). In
36 // this way all CpuReader instances can share the same symbol map instance.
37 // The object being shared is LazyKernelSymbolizer, which is cheap and always
38 // valid. LazyKernelSymbolizer may or may not contain a valid symbol map.
39 class LazyKernelSymbolizer {
40  public:
41   // Constructs an empty instance. Does NOT load any symbols upon construction.
42   // Loading and parsing happens on the first GetOrCreateKernelSymbolMap() call.
43   LazyKernelSymbolizer();
44   ~LazyKernelSymbolizer();
45 
46   // Returns |instance_|, creating it if doesn't exist or was destroyed.
47   KernelSymbolMap* GetOrCreateKernelSymbolMap();
48 
is_valid()49   bool is_valid() const { return !!symbol_map_; }
50 
51   // Destroys the |symbol_map_| freeing up memory. A further call to
52   // GetOrCreateKernelSymbolMap() will create it again.
53   void Destroy();
54 
55   // Exposed for testing.
56   static bool CanReadKernelSymbolAddresses(
57       const char* ksyms_path_for_testing = nullptr);
58 
59  private:
60   std::unique_ptr<KernelSymbolMap> symbol_map_;
61   PERFETTO_THREAD_CHECKER(thread_checker_)
62 };
63 
64 }  // namespace perfetto
65 
66 #endif  // SRC_KALLSYMS_LAZY_KERNEL_SYMBOLIZER_H_
67