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 struct TracingField {
30   std::string name;
31   size_t offset;
32   size_t elem_size;
33   size_t elem_count;
34   bool is_signed;
35 };
36 
37 struct TracingFieldPlace {
38   uint32_t offset;
39   uint32_t size;
40 
ReadFromDataTracingFieldPlace41   uint64_t ReadFromData(const char* raw_data) {
42     return ConvertBytesToValue(raw_data + offset, size);
43   }
44 };
45 
46 struct StringTracingFieldPlace {
47   uint32_t offset;
48   uint32_t size;
49 
ReadFromDataStringTracingFieldPlace50   std::string ReadFromData(const char* raw_data) {
51     char s[size + 1];
52     s[size] = '\0';
53     memcpy(s, raw_data + offset, size);
54     return s;
55   }
56 };
57 
58 struct TracingFormat {
59   std::string system_name;
60   std::string name;
61   uint64_t id;
62   std::vector<TracingField> fields;
63 
GetFieldTracingFormat64   void GetField(const std::string& name, TracingFieldPlace& place) {
65     const TracingField& field = GetField(name);
66     place.offset = field.offset;
67     place.size = field.elem_size;
68   }
69 
GetFieldTracingFormat70   void GetField(const std::string& name, StringTracingFieldPlace& place) {
71     const TracingField& field = GetField(name);
72     place.offset = field.offset;
73     place.size = field.elem_count;
74   }
75 
76  private:
GetFieldTracingFormat77   const TracingField& GetField(const std::string& name) {
78     for (const auto& field : fields) {
79       if (field.name == name) {
80         return field;
81       }
82     }
83     LOG(FATAL) << "Couldn't find field " << name << "in TracingFormat of "
84                << this->name;
85     return fields[0];
86   }
87 };
88 
89 class TracingFile;
90 
91 class Tracing {
92  public:
93   explicit Tracing(const std::vector<char>& data);
94   ~Tracing();
95   void Dump(size_t indent);
96   TracingFormat GetTracingFormatHavingId(uint64_t trace_event_id);
97   std::string GetTracingEventNameHavingId(uint64_t trace_event_id);
98   const std::string& GetKallsyms() const;
99   uint32_t GetPageSize() const;
100 
101  private:
102   TracingFile* tracing_file_;
103   std::vector<TracingFormat> tracing_formats_;
104 };
105 
106 bool GetTracingData(const std::vector<const EventType*>& event_types,
107                     std::vector<char>* data);
108 
109 // use_quote: whether or not to use quotes in string operands
110 // used_fields: field names used in the filter
111 // Return adjusted filter on success, otherwise return std::nullopt.
112 using FieldNameSet = std::set<std::string>;
113 std::optional<std::string> AdjustTracepointFilter(const std::string& filter, bool use_quote,
114                                                   FieldNameSet* used_fields);
115 std::optional<FieldNameSet> GetFieldNamesForTracepointEvent(const EventType& event);
116 
117 #endif  // SIMPLE_PERF_TRACING_H_
118