1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn * Copyright (C) 2007-2016 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#include <assert.h> 1870a83dc7b3bfd56098079c95de5d80daa9998a77Mark Salyzyn#include <ctype.h> 19a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#include <errno.h> 20a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#include <fcntl.h> 2170a83dc7b3bfd56098079c95de5d80daa9998a77Mark Salyzyn#include <inttypes.h> 22c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn#include <limits.h> 23cfd5b080af8de527d768f0ff7902c26af8d49307Mark Salyzyn#include <stdio.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mman.h> 27a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn 28700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#include <experimental/string_view> 29700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#include <functional> 30c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn#include <string> 31700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#include <unordered_map> 32700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn 33a04464adaf5b95ae953f8577632d3cf8aa2c80a3Mark Salyzyn#include <log/event_tag_map.h> 341f83aa424f537cf3f07e1d27dbbcc524818b5358Steven Moreland#include <log/log_properties.h> 352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn#include <private/android_logger.h> 36c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn#include <utils/FastStrcmp.h> 37c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn#include <utils/RWLock.h> 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "log_portability.h" 40c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn#include "logd_reader.h" 41be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark Salyzyn 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define OUT_TAG "EventTagMap" 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzynclass MapString { 452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn private: 462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const std::string* alloc; // HAS-AN 472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const std::experimental::string_view str; // HAS-A 482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn public: 502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn operator const std::experimental::string_view() const { 512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return str; 522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* data() const { 552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return str.data(); 562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t length() const { 582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return str.length(); 592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool operator==(const MapString& rval) const { 622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (length() != rval.length()) return false; 632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (length() == 0) return true; 642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return fastcmp<strncmp>(data(), rval.data(), length()) == 0; 652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool operator!=(const MapString& rval) const { 672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return !(*this == rval); 682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(const char* str, size_t len) : alloc(NULL), str(str, len) { 712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn explicit MapString(const std::string& str) 732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : alloc(new std::string(str)), str(alloc->data(), alloc->length()) { 742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(MapString&& rval) 762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : alloc(rval.alloc), str(rval.data(), rval.length()) { 772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn rval.alloc = NULL; 782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn explicit MapString(const MapString& rval) 802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : alloc(rval.alloc ? new std::string(*rval.alloc) : NULL), 812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn str(alloc ? alloc->data() : rval.data(), rval.length()) { 822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ~MapString() { 852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (alloc) delete alloc; 862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 87c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn}; 88c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 89c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn// Hash for MapString 902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyntemplate <> 912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstruct std::hash<MapString> 922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : public std::unary_function<const MapString&, size_t> { 932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t operator()(const MapString& __t) const noexcept { 942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!__t.length()) return 0; 952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return std::hash<std::experimental::string_view>()( 962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::experimental::string_view(__t)); 972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 98c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn}; 99700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn 100700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyntypedef std::pair<MapString, MapString> TagFmt; 101700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn 1022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyntemplate <> 1032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstruct std::hash<TagFmt> : public std::unary_function<const TagFmt&, size_t> { 1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t operator()(const TagFmt& __t) const noexcept { 1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Tag is typically unique. Will cost us an extra 100ns for the 1062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // unordered_map lookup if we instead did a hash that combined 1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // both of tag and fmt members, e.g.: 1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // 1092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // return std::hash<MapString>()(__t.first) ^ 1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // std::hash<MapString>()(__t.second); 1112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return std::hash<MapString>()(__t.first); 1122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 113700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn}; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Map 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct EventTagMap { 1172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn#define NUM_MAPS 2 1182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // memory-mapped source file; we get strings from here 1192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn void* mapAddr[NUM_MAPS]; 1202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t mapLen[NUM_MAPS]; 1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn private: 1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<uint32_t, TagFmt> Idx2TagFmt; 1242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<TagFmt, uint32_t> TagFmt2Idx; 1252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<MapString, uint32_t> Tag2Idx; 1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // protect unordered sets 1272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android::RWLock rwlock; 1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn public: 1302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn EventTagMap() { 1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(mapAddr, 0, sizeof(mapAddr)); 1322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(mapLen, 0, sizeof(mapLen)); 1332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ~EventTagMap() { 1362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn Idx2TagFmt.clear(); 1372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn TagFmt2Idx.clear(); 1382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn Tag2Idx.clear(); 1392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (size_t which = 0; which < NUM_MAPS; ++which) { 1402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (mapAddr[which]) { 1412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn munmap(mapAddr[which], mapLen[which]); 1422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn mapAddr[which] = 0; 1432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1447da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn } 1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose = false); 1482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const TagFmt* find(uint32_t tag) const; 1492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int find(TagFmt&& tagfmt) const; 1502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int find(MapString&& tag) const; 151700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn}; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynbool EventTagMap::emplaceUnique(uint32_t tag, const TagFmt& tagfmt, 1542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool verbose) { 1552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool ret = true; 1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char errorFormat[] = 1572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn OUT_TAG ": duplicate tag entries %" PRIu32 ":%.*s:%.*s and %" PRIu32 1582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ":%.*s:%.*s)\n"; 1592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android::RWLock::AutoWLock writeLock(rwlock); 1602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn { 1612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<uint32_t, TagFmt>::const_iterator it; 1622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = Idx2TagFmt.find(tag); 1632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it != Idx2TagFmt.end()) { 1642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (verbose) { 1652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, errorFormat, it->first, (int)it->second.first.length(), 1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it->second.first.data(), (int)it->second.second.length(), 1672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it->second.second.data(), tag, (int)tagfmt.first.length(), 1682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tagfmt.first.data(), (int)tagfmt.second.length(), 1692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tagfmt.second.data()); 1702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = false; 1722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn Idx2TagFmt.emplace(std::make_pair(tag, tagfmt)); 174c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn } 1752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 176c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 1772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn { 1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<TagFmt, uint32_t>::const_iterator it; 1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = TagFmt2Idx.find(tagfmt); 1802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it != TagFmt2Idx.end()) { 1812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (verbose) { 1822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, errorFormat, it->second, (int)it->first.first.length(), 1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it->first.first.data(), (int)it->first.second.length(), 1842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it->first.second.data(), tag, (int)tagfmt.first.length(), 1852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tagfmt.first.data(), (int)tagfmt.second.length(), 1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tagfmt.second.data()); 1872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = false; 1892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 1902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn TagFmt2Idx.emplace(std::make_pair(tagfmt, tag)); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn { 1952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<MapString, uint32_t>::const_iterator it; 1962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = Tag2Idx.find(tagfmt.first); 1972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!tagfmt.second.length() && (it != Tag2Idx.end())) { 1982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn Tag2Idx.erase(it); 1992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = Tag2Idx.end(); 200c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn } 2012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it == Tag2Idx.end()) { 2022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn Tag2Idx.emplace(std::make_pair(tagfmt.first, tag)); 2032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 205c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 2062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 209700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzynconst TagFmt* EventTagMap::find(uint32_t tag) const { 2102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<uint32_t, TagFmt>::const_iterator it; 2112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 2122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = Idx2TagFmt.find(tag); 2132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it == Idx2TagFmt.end()) return NULL; 2142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return &(it->second); 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzynint EventTagMap::find(TagFmt&& tagfmt) const { 2182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<TagFmt, uint32_t>::const_iterator it; 2192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 2202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = TagFmt2Idx.find(std::move(tagfmt)); 2212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it == TagFmt2Idx.end()) return -1; 2222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return it->second; 223c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn} 224c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 225c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzynint EventTagMap::find(MapString&& tag) const { 2262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::unordered_map<MapString, uint32_t>::const_iterator it; 2272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); 2282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn it = Tag2Idx.find(std::move(tag)); 2292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (it == Tag2Idx.end()) return -1; 2302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return it->second; 231c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn} 232c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 233700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Scan one tag line. 234700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// 235700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// "*pData" should be pointing to the first digit in the tag number. On 236700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// successful return, it will be pointing to the last character in the 237700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// tag line (i.e. the character before the start of the next line). 238700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// 2392a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// lineNum = 0 removes verbose comments and requires us to cache the 2402a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// content rather than make direct raw references since the content 2412a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// will disappear after the call. A non-zero lineNum means we own the 2422a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// data and it will outlive the call. 2432a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// 244700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Returns 0 on success, nonzero on failure. 245700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzynstatic int scanTagLine(EventTagMap* map, char** pData, int lineNum) { 2462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp; 2472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long val = strtoul(*pData, &cp, 10); 2482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (cp == *pData) { 2492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (lineNum) { 2502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", lineNum); 251700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn } 2522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 2532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 2542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 255807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn 2562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t tagIndex = val; 2572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (tagIndex != val) { 2582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (lineNum) { 2592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", lineNum); 26070a83dc7b3bfd56098079c95de5d80daa9998a77Mark Salyzyn } 2612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = ERANGE; 2622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 2632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while ((*++cp != '\n') && isspace(*cp)) { 2662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp == '\n') { 2692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (lineNum) { 2702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", lineNum); 271700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn } 2722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 2732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 2742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* tag = cp; 2772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Determine whether "c" is a valid tag char. 2782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (isalnum(*++cp) || (*cp == '_')) { 2792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t tagLen = cp - tag; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!isspace(*cp)) { 2832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (lineNum) { 2842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": invalid tag chars on line %d\n", lineNum); 2857da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn } 2862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 2872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 2882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (isspace(*cp) && (*cp != '\n')) ++cp; 2912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* fmt = NULL; 2922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t fmtLen = 0; 2932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp != '#') { 2942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fmt = cp; 2952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while ((*cp != '\n') && (*cp != '#')) ++cp; 2962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while ((cp > fmt) && isspace(*(cp - 1))) --cp; 2972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fmtLen = cp - fmt; 2982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // KISS Only report identicals if they are global 3012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Ideally we want to check if there are identicals 3022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // recorded for the same uid, but recording that 3032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // unused detail in our database is too burdensome. 3042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool verbose = true; 3052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while ((*cp != '#') && (*cp != '\n')) ++cp; 3062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp == '#') { 3072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn do { 3082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++cp; 3092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } while (isspace(*cp) && (*cp != '\n')); 3102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn verbose = !!fastcmp<strncmp>(cp, "uid=", strlen("uid=")); 3112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (*cp != '\n') ++cp; 314700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#ifdef DEBUG 3152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, "%d: %p: %.*s\n", lineNum, tag, (int)(cp - *pData), *pData); 316700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#endif 3172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *pData = cp; 3182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (lineNum) { 3202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (map->emplaceUnique(tagIndex, 3212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn TagFmt(std::make_pair(MapString(tag, tagLen), 3222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(fmt, fmtLen))), 3232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn verbose)) { 3242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 3272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // cache 3282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (map->emplaceUnique( 3292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tagIndex, 3302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn TagFmt(std::make_pair(MapString(std::string(tag, tagLen)), 3312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(std::string(fmt, fmtLen)))))) { 3322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 3332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EMLINK; 3362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3397da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzynstatic const char* eventTagFiles[NUM_MAPS] = { 3402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn EVENT_TAG_MAP_FILE, "/dev/event-log-tags", 3417da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn}; 3427da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn 343700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Parse the tags out of the file. 3447da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzynstatic int parseMapLines(EventTagMap* map, size_t which) { 3452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp = static_cast<char*>(map->mapAddr[which]); 3462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t len = map->mapLen[which]; 3472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* endp = cp + len; 348700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn 3492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // insist on EOL at EOF; simplifies parsing and null-termination 3502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!len || (*(endp - 1) != '\n')) { 351700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#ifdef DEBUG 3522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n", 3532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn which, len); 354700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn#endif 3552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (which) { // do not propagate errors for other files 3562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 3592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 3602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn bool lineStart = true; 3632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int lineNum = 1; 3642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (cp < endp) { 3652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp == '\n') { 3662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn lineStart = true; 3672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn lineNum++; 3682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else if (lineStart) { 3692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp == '#') { 3702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // comment; just scan to end 3712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn lineStart = false; 3722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else if (isdigit(*cp)) { 3732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // looks like a tag; scan it out 3742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (scanTagLine(map, &cp, lineNum) != 0) { 3752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!which || (errno != EMLINK)) { 3762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 3772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn lineNum++; // we eat the '\n' 3802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // leave lineStart==true 3812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else if (isspace(*cp)) { 3822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // looks like leading whitespace; keep scanning 3832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 3842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, 3852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn OUT_TAG 3862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ": unexpected chars (0x%02x) in tag number on line %d\n", 3872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *cp, lineNum); 3882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 3892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 3902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 3922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // this is a blank or comment line 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cp++; 3952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return 0; 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 400700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Open the map file and allocate a structure to manage it. 401700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// 402700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// We create a private mapping because we want to terminate the log tag 403700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// strings with '\0'. 404700fb87648047d23c947d9020fd35cd47621dc7cMark SalyzynLIBLOG_ABI_PUBLIC EventTagMap* android_openEventTagMap(const char* fileName) { 4052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn EventTagMap* newTagMap; 4062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn off_t end[NUM_MAPS]; 4072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int save_errno, fd[NUM_MAPS]; 4082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t which; 4097da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn 4102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(fd, -1, sizeof(fd)); 4112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn memset(end, 0, sizeof(end)); 4127da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn 4132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (which = 0; which < NUM_MAPS; ++which) { 4142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* tagfile = fileName ? fileName : eventTagFiles[which]; 4157da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn 4162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fd[which] = open(tagfile, O_RDONLY | O_CLOEXEC); 4172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (fd[which] < 0) { 4182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!which) { 419700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn save_errno = errno; 4202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": unable to open map '%s': %s\n", tagfile, 4212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strerror(save_errno)); 4222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn goto fail_errno; 4232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn continue; 42570a83dc7b3bfd56098079c95de5d80daa9998a77Mark Salyzyn } 4262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn end[which] = lseek(fd[which], 0L, SEEK_END); 4272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn save_errno = errno; 4282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (void)lseek(fd[which], 0L, SEEK_SET); 4292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!which && (end[0] < 0)) { 4302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": unable to seek map '%s' %s\n", tagfile, 4312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strerror(save_errno)); 4322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn goto fail_close; 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 4342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (fileName) break; // Only allow one as specified 4352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn newTagMap = new EventTagMap; 4382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (newTagMap == NULL) { 4392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn save_errno = errno; 4402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn goto fail_close; 4412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (which = 0; which < NUM_MAPS; ++which) { 4442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (fd[which] >= 0) { 4452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn newTagMap->mapAddr[which] = 4462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn mmap(NULL, end[which], which ? PROT_READ : PROT_READ | PROT_WRITE, 4472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn which ? MAP_SHARED : MAP_PRIVATE, fd[which], 0); 4482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn save_errno = errno; 4492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn close(fd[which]); 4502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fd[which] = -1; 4512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((newTagMap->mapAddr[which] != MAP_FAILED) && 4522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn (newTagMap->mapAddr[which] != NULL)) { 4532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn newTagMap->mapLen[which] = end[which]; 4542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else if (!which) { 4552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* tagfile = fileName ? fileName : eventTagFiles[which]; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn fprintf(stderr, OUT_TAG ": mmap(%s) failed: %s\n", tagfile, 4582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strerror(save_errno)); 4592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn goto fail_unmap; 4602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 46170a83dc7b3bfd56098079c95de5d80daa9998a77Mark Salyzyn } 4622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (which = 0; which < NUM_MAPS; ++which) { 4652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (parseMapLines(newTagMap, which) != 0) { 4662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn delete newTagMap; 4672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return NULL; 468530711b39e0447b0ce6824de936cedc294634e0eMark Salyzyn } 4692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 470530711b39e0447b0ce6824de936cedc294634e0eMark Salyzyn 4712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return newTagMap; 4727da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzyn 4737da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzynfail_unmap: 4742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn save_errno = EINVAL; 4752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn delete newTagMap; 4767da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzynfail_close: 4772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (which = 0; which < NUM_MAPS; ++which) close(fd[which]); 4787da7fab790ca6cfff2755cf8c86b20b739b919adMark Salyzynfail_errno: 4792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = save_errno; 4802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return NULL; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 483700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Close the map. 484700fb87648047d23c947d9020fd35cd47621dc7cMark SalyzynLIBLOG_ABI_PUBLIC void android_closeEventTagMap(EventTagMap* map) { 4852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (map) delete map; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4882a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// Cache miss, go to logd to acquire a public reference. 4892a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn// Because we lack access to a SHARED PUBLIC /dev/event-log-tags file map? 4902a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzynstatic const TagFmt* __getEventTag(EventTagMap* map, unsigned int tag) { 4912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // call event tag service to arrange for a new tag 4922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* buf = NULL; 4932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Can not use android::base::StringPrintf, asprintf + free instead. 4942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char command_template[] = "getEventTag id=%u"; 4952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int ret = asprintf(&buf, command_template, tag); 4962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (ret > 0) { 4972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Add some buffer margin for an estimate of the full return content. 4982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp; 4992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t size = 5002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret - strlen(command_template) + 5012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); 5022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (size > (size_t)ret) { 5032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cp = static_cast<char*>(realloc(buf, size)); 5042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (cp) { 5052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf = cp; 5062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 5072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size = ret; 5082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 5102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size = ret; 5112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Ask event log tag service for an existing entry 5132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (__send_log_msg(buf, size) >= 0) { 5142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[size - 1] = '\0'; 5152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long val = strtoul(buf, &cp, 10); // return size 5162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK 5172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++cp; 5182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!scanTagLine(map, &cp, 0)) { 5192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn free(buf); 5202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return map->find(tag); 5212a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn } 5222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5232a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn } 5242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn free(buf); 5252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return NULL; 5272a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn} 5282a0044e4b00e7529dc8bc49464ec7b31b2e544f4Mark Salyzyn 529700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Look up an entry in the map. 530700fb87648047d23c947d9020fd35cd47621dc7cMark SalyzynLIBLOG_ABI_PUBLIC const char* android_lookupEventTag_len(const EventTagMap* map, 5312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t* len, 532700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn unsigned int tag) { 5332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len) *len = 0; 5342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const TagFmt* str = map->find(tag); 5352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!str) { 5362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn str = __getEventTag(const_cast<EventTagMap*>(map), tag); 5372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!str) return NULL; 5392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len) *len = str->first.length(); 5402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return str->first.data(); 541700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn} 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 543700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// Look up an entry in the map. 544700fb87648047d23c947d9020fd35cd47621dc7cMark SalyzynLIBLOG_ABI_PUBLIC const char* android_lookupEventFormat_len( 5452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const EventTagMap* map, size_t* len, unsigned int tag) { 5462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len) *len = 0; 5472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const TagFmt* str = map->find(tag); 5482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!str) { 5492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn str = __getEventTag(const_cast<EventTagMap*>(map), tag); 5502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!str) return NULL; 5522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (len) *len = str->second.length(); 5532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return str->second.data(); 554700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn} 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 556700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// This function is deprecated and replaced with android_lookupEventTag_len 557700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// since it will cause the map to change from Shared and backed by a file, 558700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// to Private Dirty and backed up by swap, albeit highly compressible. By 559700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn// deprecating this function everywhere, we save 100s of MB of memory space. 560700fb87648047d23c947d9020fd35cd47621dc7cMark SalyzynLIBLOG_ABI_PUBLIC const char* android_lookupEventTag(const EventTagMap* map, 561700fb87648047d23c947d9020fd35cd47621dc7cMark Salyzyn unsigned int tag) { 5622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t len; 5632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* tagStr = android_lookupEventTag_len(map, &len, tag); 5642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!tagStr) return tagStr; 5662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp = const_cast<char*>(tagStr); 5672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cp += len; 5682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp) *cp = '\0'; // Trigger copy on write :-( and why deprecated. 5692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return tagStr; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 571c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 572c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn// Look up tagname, generate one if necessary, and return a tag 573c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark SalyzynLIBLOG_ABI_PUBLIC int android_lookupEventTagNum(EventTagMap* map, 574c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn const char* tagname, 5752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* format, int prio) { 5762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t len = strlen(tagname); 5772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!len) { 5782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EINVAL; 5792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 5802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((prio != ANDROID_LOG_UNKNOWN) && (prio < ANDROID_LOG_SILENT) && 5832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn !__android_log_is_loggable_len(prio, tagname, len, 5842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn __android_log_is_debuggable() 5852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ? ANDROID_LOG_VERBOSE 5862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : ANDROID_LOG_DEBUG)) { 5872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn errno = EPERM; 5882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return -1; 5892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!format) format = ""; 5922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ssize_t fmtLen = strlen(format); 5932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int ret = map->find(TagFmt( 5942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn std::make_pair(MapString(tagname, len), MapString(format, fmtLen)))); 5952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (ret != -1) return ret; 5962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // call event tag service to arrange for a new tag 5982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* buf = NULL; 5992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Can not use android::base::StringPrintf, asprintf + free instead. 6002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char command_template[] = "getEventTag name=%s format=\"%s\""; 6012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = asprintf(&buf, command_template, tagname, format); 6022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (ret > 0) { 6032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Add some buffer margin for an estimate of the full return content. 6042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp; 6052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t size = 6062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret - strlen(command_template) + 6072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); 6082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (size > (size_t)ret) { 6092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cp = static_cast<char*>(realloc(buf, size)); 6102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (cp) { 6112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf = cp; 6122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 6132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size = ret; 6142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 6152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 6162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size = ret; 617c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn } 6182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Ask event log tag service for an allocation 6192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (__send_log_msg(buf, size) >= 0) { 6202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn buf[size - 1] = '\0'; 6212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long val = strtoul(buf, &cp, 10); // return size 6222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK 6232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn val = strtoul(cp + 1, &cp, 10); // allocated tag number 6242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((val > 0) && (val < UINT32_MAX) && (*cp == '\t')) { 6252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn free(buf); 6262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = val; 6272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // cache 6282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn map->emplaceUnique(ret, TagFmt(std::make_pair( 6292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(std::string(tagname, len)), 6302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn MapString(std::string(format, fmtLen))))); 6312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 632c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn } 6332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 634c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn } 6352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn free(buf); 6362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 637c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn 6382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // Hail Mary 6392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = map->find(MapString(tagname, len)); 6402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (ret == -1) errno = ESRCH; 6412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 642c9e5f3716626fb8fcbde87c2f7324cc9292a0bd5Mark Salyzyn} 643