xref: /aosp_15_r20/system/extras/simpleperf/ETMDecoder.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #pragma once
18*288bf522SAndroid Build Coastguard Worker 
19*288bf522SAndroid Build Coastguard Worker #include <functional>
20*288bf522SAndroid Build Coastguard Worker #include <memory>
21*288bf522SAndroid Build Coastguard Worker #include <string>
22*288bf522SAndroid Build Coastguard Worker 
23*288bf522SAndroid Build Coastguard Worker #include <android-base/expected.h>
24*288bf522SAndroid Build Coastguard Worker 
25*288bf522SAndroid Build Coastguard Worker #include "record.h"
26*288bf522SAndroid Build Coastguard Worker #include "thread_tree.h"
27*288bf522SAndroid Build Coastguard Worker 
28*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
29*288bf522SAndroid Build Coastguard Worker 
30*288bf522SAndroid Build Coastguard Worker struct ETMDumpOption {
31*288bf522SAndroid Build Coastguard Worker   bool dump_raw_data = false;
32*288bf522SAndroid Build Coastguard Worker   bool dump_packets = false;
33*288bf522SAndroid Build Coastguard Worker   bool dump_elements = false;
34*288bf522SAndroid Build Coastguard Worker };
35*288bf522SAndroid Build Coastguard Worker 
36*288bf522SAndroid Build Coastguard Worker bool ParseEtmDumpOption(const std::string& s, ETMDumpOption* option);
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker struct ETMInstrRange {
39*288bf522SAndroid Build Coastguard Worker   // the binary containing the instruction range
40*288bf522SAndroid Build Coastguard Worker   Dso* dso = nullptr;
41*288bf522SAndroid Build Coastguard Worker   // the address of the first instruction in the binary
42*288bf522SAndroid Build Coastguard Worker   uint64_t start_addr = 0;
43*288bf522SAndroid Build Coastguard Worker   // the address of the last instruction in the binary
44*288bf522SAndroid Build Coastguard Worker   uint64_t end_addr = 0;
45*288bf522SAndroid Build Coastguard Worker   // If the last instruction is a branch instruction, and it branches
46*288bf522SAndroid Build Coastguard Worker   // to a fixed location in the same binary, then branch_to_addr points
47*288bf522SAndroid Build Coastguard Worker   // to the branched to instruction.
48*288bf522SAndroid Build Coastguard Worker   uint64_t branch_to_addr = 0;
49*288bf522SAndroid Build Coastguard Worker   // times the branch is taken
50*288bf522SAndroid Build Coastguard Worker   uint64_t branch_taken_count = 0;
51*288bf522SAndroid Build Coastguard Worker   // times the branch isn't taken
52*288bf522SAndroid Build Coastguard Worker   uint64_t branch_not_taken_count = 0;
53*288bf522SAndroid Build Coastguard Worker };
54*288bf522SAndroid Build Coastguard Worker 
55*288bf522SAndroid Build Coastguard Worker struct ETMBranchList {
56*288bf522SAndroid Build Coastguard Worker   // the binary containing the branch list
57*288bf522SAndroid Build Coastguard Worker   Dso* dso = nullptr;
58*288bf522SAndroid Build Coastguard Worker   // the instruction address before the first branch. Bit 0 is set for thumb instructions.
59*288bf522SAndroid Build Coastguard Worker   uint64_t addr = 0;
60*288bf522SAndroid Build Coastguard Worker   // the branch list (one bit for each branch, true for branch taken, false for not taken)
61*288bf522SAndroid Build Coastguard Worker   std::vector<bool> branch;
62*288bf522SAndroid Build Coastguard Worker };
63*288bf522SAndroid Build Coastguard Worker 
64*288bf522SAndroid Build Coastguard Worker // ThreadTree interface used by ETMDecoder
65*288bf522SAndroid Build Coastguard Worker class ETMThreadTree {
66*288bf522SAndroid Build Coastguard Worker  public:
~ETMThreadTree()67*288bf522SAndroid Build Coastguard Worker   virtual ~ETMThreadTree() {}
68*288bf522SAndroid Build Coastguard Worker   virtual void DisableThreadExitRecords() = 0;
69*288bf522SAndroid Build Coastguard Worker   virtual const ThreadEntry* FindThread(int tid) = 0;
70*288bf522SAndroid Build Coastguard Worker   virtual const MapSet& GetKernelMaps() = 0;
71*288bf522SAndroid Build Coastguard Worker };
72*288bf522SAndroid Build Coastguard Worker 
73*288bf522SAndroid Build Coastguard Worker class ETMDecoder {
74*288bf522SAndroid Build Coastguard Worker  public:
75*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ETMDecoder> Create(const AuxTraceInfoRecord& auxtrace_info,
76*288bf522SAndroid Build Coastguard Worker                                             ETMThreadTree& thread_tree);
~ETMDecoder()77*288bf522SAndroid Build Coastguard Worker   virtual ~ETMDecoder() {}
78*288bf522SAndroid Build Coastguard Worker   virtual void EnableDump(const ETMDumpOption& option) = 0;
79*288bf522SAndroid Build Coastguard Worker 
80*288bf522SAndroid Build Coastguard Worker   using InstrRangeCallbackFn = std::function<void(const ETMInstrRange&)>;
81*288bf522SAndroid Build Coastguard Worker   virtual void RegisterCallback(const InstrRangeCallbackFn& callback) = 0;
82*288bf522SAndroid Build Coastguard Worker 
83*288bf522SAndroid Build Coastguard Worker   using BranchListCallbackFn = std::function<void(const ETMBranchList&)>;
84*288bf522SAndroid Build Coastguard Worker   virtual void RegisterCallback(const BranchListCallbackFn& callback) = 0;
85*288bf522SAndroid Build Coastguard Worker 
86*288bf522SAndroid Build Coastguard Worker   virtual bool ProcessData(const uint8_t* data, size_t size, bool formatted, uint32_t cpu) = 0;
87*288bf522SAndroid Build Coastguard Worker   virtual bool FinishData() = 0;
88*288bf522SAndroid Build Coastguard Worker };
89*288bf522SAndroid Build Coastguard Worker 
90*288bf522SAndroid Build Coastguard Worker // Map from addrs to a map of (branch_list, count).
91*288bf522SAndroid Build Coastguard Worker // Use maps instead of unordered_maps. Because it helps locality by decoding instructions for sorted
92*288bf522SAndroid Build Coastguard Worker // addresses.
93*288bf522SAndroid Build Coastguard Worker using ETMBranchMap = std::map<uint64_t, std::map<std::vector<bool>, uint64_t>>;
94*288bf522SAndroid Build Coastguard Worker 
95*288bf522SAndroid Build Coastguard Worker android::base::expected<void, std::string> ConvertETMBranchMapToInstrRanges(
96*288bf522SAndroid Build Coastguard Worker     Dso* dso, const ETMBranchMap& branch_map, const ETMDecoder::InstrRangeCallbackFn& callback);
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf