167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui/* 267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Copyright (C) 2015 The Android Open Source Project 367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * you may not use this file except in compliance with the License. 667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * You may obtain a copy of the License at 767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * http://www.apache.org/licenses/LICENSE-2.0 967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 1067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Unless required by applicable law or agreed to in writing, software 1167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * distributed under the License is distributed on an "AS IS" BASIS, 1267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * See the License for the specific language governing permissions and 1467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * limitations under the License. 1567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui */ 1667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_type.h" 1867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <unistd.h> 20f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui#include <algorithm> 2167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <string> 2267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <vector> 239759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui 2466dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/file.h> 2566dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/logging.h> 269759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui 2767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_attr.h" 28f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui#include "utils.h" 2967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 3042aa127e8ab4c5eb5197cf3cc68470cf3a0fdcbbYabin Cui#define EVENT_TYPE_TABLE_ENTRY(name, type, config) {name, type, config}, 3167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 32f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cuistatic const std::vector<EventType> static_event_type_array = { 3367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "event_type_table.h" 3467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui}; 3567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 36f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cuistatic const std::vector<EventType> GetTracepointEventTypes() { 37f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<EventType> result; 38f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui const std::string tracepoint_dirname = "/sys/kernel/debug/tracing/events"; 39f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<std::string> system_dirs; 40f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui GetEntriesInDir(tracepoint_dirname, nullptr, &system_dirs); 41f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& system_name : system_dirs) { 42f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string system_path = tracepoint_dirname + "/" + system_name; 43f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::vector<std::string> event_dirs; 44f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui GetEntriesInDir(system_path, nullptr, &event_dirs); 45f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& event_name : event_dirs) { 46f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string id_path = system_path + "/" + event_name + "/id"; 47f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::string id_content; 48f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (!android::base::ReadFileToString(id_path, &id_content)) { 49f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui continue; 50f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 51f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui char* endptr; 52f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui uint64_t id = strtoull(id_content.c_str(), &endptr, 10); 53f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (endptr == id_content.c_str()) { 54f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui LOG(DEBUG) << "unexpected id '" << id_content << "' in " << id_path; 55f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui continue; 56f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 57f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui result.push_back(EventType(system_name + ":" + event_name, PERF_TYPE_TRACEPOINT, id)); 58f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 59f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 60f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui std::sort(result.begin(), result.end(), 61f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui [](const EventType& type1, const EventType& type2) { return type1.name < type2.name; }); 62f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui return result; 63f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui} 64f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui 65d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cuiconst std::vector<EventType>& GetAllEventTypes() { 66f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui static std::vector<EventType> event_type_array; 67f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui if (event_type_array.empty()) { 68f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui event_type_array.insert(event_type_array.end(), static_event_type_array.begin(), 69f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui static_event_type_array.end()); 70f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui const std::vector<EventType> tracepoint_array = GetTracepointEventTypes(); 71f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui event_type_array.insert(event_type_array.end(), tracepoint_array.begin(), 72f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui tracepoint_array.end()); 73f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui } 7467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui return event_type_array; 7567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 7667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 77d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cuiconst EventType* FindEventTypeByConfig(uint32_t type, uint64_t config) { 78d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (auto& event_type : GetAllEventTypes()) { 79d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type.type == type && event_type.config == config) { 80d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return &event_type; 81d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 82d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 83d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return nullptr; 84d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui} 85d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui 869fd3cc1048a3d0338df4a48760dfd655560992a1Yabin Cuiconst EventType* FindEventTypeByName(const std::string& name) { 879759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui const EventType* result = nullptr; 88f569b478e74560a2d9e29a96824e16b93a55b97fYabin Cui for (auto& event_type : GetAllEventTypes()) { 8967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui if (event_type.name == name) { 909759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui result = &event_type; 919759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui break; 9267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 9367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 949759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui if (result == nullptr) { 959759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui LOG(ERROR) << "Unknown event_type '" << name 969759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui << "', try `simpleperf list` to list all possible event type names"; 979759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui return nullptr; 989759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui } 999759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui return result; 10067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 10167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1029fd3cc1048a3d0338df4a48760dfd655560992a1Yabin Cuistd::unique_ptr<EventTypeAndModifier> ParseEventType(const std::string& event_type_str) { 103d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui static std::string modifier_characters = "ukhGHp"; 104d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui std::unique_ptr<EventTypeAndModifier> event_type_modifier(new EventTypeAndModifier); 1055872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_modifier->name = event_type_str; 1065872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui std::string event_type_name = event_type_str; 107d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui std::string modifier; 108d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui size_t comm_pos = event_type_str.rfind(':'); 109d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (comm_pos != std::string::npos) { 110d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui bool match_modifier = true; 111d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (size_t i = comm_pos + 1; i < event_type_str.size(); ++i) { 112d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui char c = event_type_str[i]; 113d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (c != ' ' && modifier_characters.find(c) == std::string::npos) { 114d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui match_modifier = false; 115d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 116d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 117d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 118d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (match_modifier) { 1195872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_name = event_type_str.substr(0, comm_pos); 120d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui modifier = event_type_str.substr(comm_pos + 1); 12167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 12267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui } 1235872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui const EventType* event_type = FindEventTypeByName(event_type_name); 124d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type == nullptr) { 125d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui // Try if the modifier belongs to the event type name, like some tracepoint events. 126d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (!modifier.empty()) { 1275872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type_name = event_type_str; 128d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui modifier.clear(); 1295872ac6f1f5b804ffea38ff59025441618802d6bYabin Cui event_type = FindEventTypeByName(event_type_name); 130d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 131d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (event_type == nullptr) { 132d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return nullptr; 133d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 134d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 135d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->event_type = *event_type; 136d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (modifier.find_first_of("ukh") != std::string::npos) { 137d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_user = true; 138d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_kernel = true; 139d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_hv = true; 140d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 141d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui if (modifier.find_first_of("GH") != std::string::npos) { 142d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_guest = true; 143d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_host = true; 144d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 145d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui 146d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui for (auto& c : modifier) { 147d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui switch (c) { 148d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'u': 149d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_user = false; 150d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 151d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'k': 152d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_kernel = false; 153d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 154d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'h': 155d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_hv = false; 156d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 157d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'G': 158d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_guest = false; 159d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 160d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'H': 161d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->exclude_host = false; 162d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 163d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case 'p': 164d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui event_type_modifier->precise_ip++; 165d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 166d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui case ' ': 167d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui break; 168d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui default: 169d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui LOG(ERROR) << "Unknown event type modifier '" << c << "'"; 170d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 171d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui } 17204d08a35c5e1cabdf6eb7397536a790b0ff44459Yabin Cui event_type_modifier->modifier = modifier; 173d115b2f738f2cef352877b26c2d93460ac9fea25Yabin Cui return event_type_modifier; 17467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 175