• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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_TRACE_PROCESSOR_IMPORTERS_ETM_ELEMENT_CURSOR_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_ETM_ELEMENT_CURSOR_H_
19 
20 #include <cstdint>
21 #include <limits>
22 #include <memory>
23 #include <optional>
24 
25 #include "perfetto/base/status.h"
26 #include "src/trace_processor/importers/etm/etm_v4_decoder.h"
27 #include "src/trace_processor/importers/etm/opencsd.h"
28 #include "src/trace_processor/storage/trace_storage.h"
29 #include "src/trace_processor/tables/etm_tables_py.h"
30 
31 namespace perfetto::trace_processor::etm {
32 
33 class MappingVersion;
34 class TargetMemory;
35 class TargetMemoryReader;
36 struct InstructionRangeSqlValue;
37 
38 class ElementTypeMask {
39  public:
IsCompatibleValue(ocsd_gen_trc_elem_t type)40   static constexpr bool IsCompatibleValue(ocsd_gen_trc_elem_t type) {
41 #if defined(__clang__)
42 #pragma clang diagnostic push
43 #pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
44 #endif
45     return type < 64;
46 #if defined(__clang__)
47 #pragma clang diagnostic pop
48 #endif
49   }
ElementTypeMask()50   ElementTypeMask() : mask_(0) {}
51 
52   ElementTypeMask& operator&=(const ElementTypeMask& o) {
53     mask_ &= o.mask_;
54     return *this;
55   }
56 
clear()57   void clear() { mask_ = 0; }
set_all()58   void set_all() { mask_ = std::numeric_limits<uint64_t>::max(); }
59 
empty()60   bool empty() const { return mask_ == 0; }
61 
matches(ocsd_gen_trc_elem_t type)62   bool matches(ocsd_gen_trc_elem_t type) const {
63     return mask_ & (1ull << type);
64   }
65 
set_bit(ocsd_gen_trc_elem_t type)66   void set_bit(ocsd_gen_trc_elem_t type) { mask_ &= (1ull << type); }
67 
68  private:
69   friend class ElementCursor;
70   uint64_t mask_;
71 };
72 
73 // Helper class to feed data to an `EtmV4Decoder` that offers a Sqlite friendly
74 // API.
75 // Given a trace this class will allow you to iterate the ETM elements contained
76 // in it. It also give you the ability to filter out some elements.
77 class ElementCursor : public EtmV4Decoder::Delegate {
78  public:
79   explicit ElementCursor(TraceStorage* storage);
80   ~ElementCursor() override;
81 
82   base::Status Filter(std::optional<tables::EtmV4TraceTable::Id> trace_id,
83                       ElementTypeMask type_mask);
84 
85   base::Status Next();
Eof()86   bool Eof() { return !needs_flush_ && data_ == data_end_; }
87 
trace_id()88   tables::EtmV4TraceTable::Id trace_id() const { return *trace_id_; }
index()89   ocsd_trc_index_t index() const {
90     return static_cast<uintptr_t>(data_ - data_start_);
91   }
element_index()92   uint32_t element_index() const { return element_index_; }
93 
element()94   const OcsdTraceElement& element() const { return *element_; }
95 
storage()96   const TraceStorage* storage() const { return storage_; }
97 
mapping()98   const MappingVersion* mapping() const { return mapping_; }
99 
has_instruction_range()100   bool has_instruction_range() const {
101     return element_->getType() == OCSD_GEN_TRC_ELEM_INSTR_RANGE;
102   }
103 
104   std::unique_ptr<InstructionRangeSqlValue> GetInstructionRange() const;
105 
106  private:
107   void SetAtEof();
108   base::Status ResetDecoder(tables::EtmV4ConfigurationTable::Id config_id);
109   ocsd_datapath_resp_t TraceElemIn(const ocsd_trc_index_t index_sop,
110                                    const uint8_t trc_chan_id,
111                                    const OcsdTraceElement& elem,
112                                    const MappingVersion* mapping) override;
113 
114   TraceStorage* storage_;
115   ElementTypeMask type_mask_;
116   std::unique_ptr<TargetMemoryReader> reader_;
117   std::unique_ptr<EtmV4Decoder> decoder_;
118   // Configuration used to create the above decoder
119   std::optional<tables::EtmV4ConfigurationTable::Id> config_id_;
120   std::optional<tables::EtmV4TraceTable::Id> trace_id_;
121 
122   const uint8_t* data_start_;
123   const uint8_t* data_;
124   const uint8_t* data_end_;
125   bool needs_flush_ = false;
126   uint32_t element_index_;
127   const OcsdTraceElement* element_;
128   const MappingVersion* mapping_;
129 };
130 
131 }  // namespace perfetto::trace_processor::etm
132 
133 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_ETM_ELEMENT_CURSOR_H_
134