1 /*
2  * Copyright (C) 2015 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 SIMPLE_PERF_OFFLINE_UNWINDER_H_
18 #define SIMPLE_PERF_OFFLINE_UNWINDER_H_
19 
20 #include <memory>
21 #include <vector>
22 
23 #include "perf_regs.h"
24 #include "thread_tree.h"
25 
26 namespace simpleperf {
27 struct ThreadEntry;
28 
29 struct UnwindingResult {
30   // time used for unwinding, in ns.
31   uint64_t used_time;
32   enum {
33     UNKNOWN_REASON,
34     EXCEED_MAX_FRAMES_LIMIT,
35     ACCESS_REG_FAILED,
36     ACCESS_STACK_FAILED,
37     ACCESS_MEM_FAILED,
38     FIND_PROC_INFO_FAILED,
39     EXECUTE_DWARF_INSTRUCTION_FAILED,
40     DIFFERENT_ARCH,
41     MAP_MISSING,
42   } stop_reason;
43   union {
44     // for ACCESS_REG_FAILED
45     uint64_t regno;
46     // for ACCESS_MEM_FAILED and ACCESS_STACK_FAILED
47     uint64_t addr;
48   } stop_info;
49   uint64_t stack_start;
50   uint64_t stack_end;
51 };
52 
53 class OfflineUnwinder {
54  public:
55   static std::unique_ptr<OfflineUnwinder> Create(bool collect_stat);
~OfflineUnwinder()56   virtual ~OfflineUnwinder() {}
57 
58   virtual bool UnwindCallChain(const ThreadEntry& thread, const RegSet& regs, const char* stack,
59                                size_t stack_size, std::vector<uint64_t>* ips,
60                                std::vector<uint64_t>* sps) = 0;
61 
GetUnwindingResult()62   const UnwindingResult& GetUnwindingResult() const {
63     return unwinding_result_;
64   }
65 
IsCallChainBrokenForIncompleteJITDebugInfo()66   bool IsCallChainBrokenForIncompleteJITDebugInfo() {
67     return is_callchain_broken_for_incomplete_jit_debug_info_;
68   }
69 
70  protected:
OfflineUnwinder()71   OfflineUnwinder() {}
72 
73   UnwindingResult unwinding_result_;
74   bool is_callchain_broken_for_incomplete_jit_debug_info_ = false;
75 };
76 
77 } // namespace simpleperf
78 
79 #endif  // SIMPLE_PERF_OFFLINE_UNWINDER_H_
80