1 /*
2  * Copyright (C) 2016 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_TRACING_H_
18 #define SIMPLE_PERF_TRACING_H_
19 
20 #include <optional>
21 #include <set>
22 #include <vector>
23 
24 #include <android-base/logging.h>
25 
26 #include "event_type.h"
27 #include "utils.h"
28 
29 namespace simpleperf {
30 
31 struct TracingField {
32   std::string name;
33   size_t offset = 0;
34   size_t elem_size = 0;
35   size_t elem_count = 1;
36   bool is_signed = false;
37   bool is_dynamic = false;
38 
39   bool operator==(const TracingField& other) const {
40     return name == other.name && offset == other.offset && elem_size == other.elem_size &&
41            elem_count == other.elem_count && is_signed == other.is_signed &&
42            is_dynamic == other.is_dynamic;
43   }
44 };
45 
46 struct TracingFieldPlace {
47   uint32_t offset;
48   uint32_t size;
49 
ReadFromDataTracingFieldPlace50   uint64_t ReadFromData(const char* raw_data) {
51     return ConvertBytesToValue(raw_data + offset, size);
52   }
53 };
54 
55 struct StringTracingFieldPlace {
56   uint32_t offset;
57   uint32_t size;
58 
ReadFromDataStringTracingFieldPlace59   std::string ReadFromData(const char* raw_data) {
60     char s[size + 1];
61     s[size] = '\0';
62     memcpy(s, raw_data + offset, size);
63     return s;
64   }
65 };
66 
67 struct TracingFormat {
68   std::string system_name;
69   std::string name;
70   uint64_t id;
71   std::vector<TracingField> fields;
72 
GetFieldTracingFormat73   void GetField(const std::string& name, TracingFieldPlace& place) {
74     const TracingField& field = GetField(name);
75     place.offset = field.offset;
76     place.size = field.elem_size;
77   }
78 
GetFieldTracingFormat79   void GetField(const std::string& name, StringTracingFieldPlace& place) {
80     const TracingField& field = GetField(name);
81     place.offset = field.offset;
82     place.size = field.elem_count;
83   }
84 
85  private:
GetFieldTracingFormat86   const TracingField& GetField(const std::string& name) {
87     for (const auto& field : fields) {
88       if (field.name == name) {
89         return field;
90       }
91     }
92     LOG(FATAL) << "Couldn't find field " << name << "in TracingFormat of " << this->name;
93     return fields[0];
94   }
95 };
96 
97 class TracingFile;
98 
99 class Tracing {
100  public:
101   explicit Tracing(const std::vector<char>& data);
102   ~Tracing();
103   void Dump(size_t indent);
104   TracingFormat GetTracingFormatHavingId(uint64_t trace_event_id);
105   std::string GetTracingEventNameHavingId(uint64_t trace_event_id);
106   const std::string& GetKallsyms() const;
107   uint32_t GetPageSize() const;
108 
109  private:
110   TracingFile* tracing_file_;
111   std::vector<TracingFormat> tracing_formats_;
112 };
113 
114 bool GetTracingData(const std::vector<const EventType*>& event_types, std::vector<char>* data);
115 
116 // use_quote: whether or not to use quotes in string operands
117 // used_fields: field names used in the filter
118 // Return adjusted filter on success, otherwise return std::nullopt.
119 using FieldNameSet = std::set<std::string>;
120 std::optional<std::string> AdjustTracepointFilter(const std::string& filter, bool use_quote,
121                                                   FieldNameSet* used_fields);
122 std::optional<FieldNameSet> GetFieldNamesForTracepointEvent(const EventType& event);
123 TracingFormat ParseTracingFormat(const std::string& data);
124 
125 }  // namespace simpleperf
126 
127 #endif  // SIMPLE_PERF_TRACING_H_
128