/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>

#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/stringprintf.h>
#include <log/log_event_list.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>

#include "LogTags.h"
#include "LogUtils.h"

static LogTags* logtags;

const char LogTags::system_event_log_tags[] = "/system/etc/event-log-tags";
const char LogTags::dynamic_event_log_tags[] = "/dev/event-log-tags";
// Only for debug
const char LogTags::debug_event_log_tags[] = "/data/misc/logd/event-log-tags";

// Sniff for first uid=%d in utf8z comment string
static uid_t sniffUid(const char* comment, const char* endp) {
    if (!comment) return AID_ROOT;

    if (*comment == '#') ++comment;
    while ((comment < endp) && (*comment != '\n') && isspace(*comment)) ++comment;
    static const char uid_str[] = "uid=";
    if (((comment + strlen(uid_str)) >= endp) ||
            fastcmp<strncmp>(comment, uid_str, strlen(uid_str)) ||
            !isdigit(comment[strlen(uid_str)])) return AID_ROOT;
    char* cp;
    unsigned long Uid = strtoul(comment + 4, &cp, 10);
    if ((cp > endp) || (Uid >= INT_MAX)) return AID_ROOT;

    return Uid;
}

// Checks for file corruption, and report false if there was no need
// to rebuild the referenced file.  Failure to rebuild is only logged,
// does not cause a return value of false.
bool LogTags::RebuildFileEventLogTags(const char* filename, bool warn) {
    int fd;

    {
        android::RWLock::AutoRLock readLock(rwlock);

        if (tag2total.begin() == tag2total.end()) {
            return false;
        }

        file2watermark_const_iterator iwater = file2watermark.find(filename);
        if (iwater == file2watermark.end()) {
            return false;
        }

        struct stat sb;
        if (!stat(filename, &sb) && ((size_t)sb.st_size >= iwater->second)) {
            return false;
        }

        // dump what we already know back into the file?
        fd = TEMP_FAILURE_RETRY(open(filename,
                                     O_WRONLY | O_TRUNC | O_CLOEXEC |
                                     O_NOFOLLOW | O_BINARY));
        if (fd >= 0) {
            time_t now = time(NULL);
            struct tm tm;
            localtime_r(&now, &tm);
            char timebuf[20];
            size_t len = strftime(timebuf, sizeof(timebuf),
                                  "%Y-%m-%d %H:%M:%S", &tm);
            android::base::WriteStringToFd(
                android::base::StringPrintf(
                    "# Rebuilt %.20s, content owned by logd\n", timebuf),
                fd);
            for (const auto& it : tag2total) {
                android::base::WriteStringToFd(formatEntry_locked(it.first,
                                                                  AID_ROOT),
                                               fd);
            }
            TEMP_FAILURE_RETRY(close(fd));
        }
    }

    if (warn) {
        android::prdebug(((fd < 0) ?
                              "%s failed to rebuild" :
                              "%s missing, damaged or truncated; rebuilt"),
                         filename);
    }

    if (fd >= 0) {
        android::RWLock::AutoWLock writeLock(rwlock);

        struct stat sb;
        if (!stat(filename, &sb)) file2watermark[filename] = sb.st_size;
    }

    return true;
}

void LogTags::AddEventLogTags(uint32_t tag, uid_t uid,
                              const std::string& Name,
                              const std::string& Format,
                              const char* source, bool warn) {
    std::string Key = Name;
    if (Format.length()) Key += "+" + Format;

    bool update = !source || !!strcmp(source, system_event_log_tags);
    bool newOne;

    {
        android::RWLock::AutoWLock writeLock(rwlock);

        tag2total_const_iterator itot = tag2total.find(tag);

        // unlikely except for dupes, or updates to uid list (more later)
        if (itot != tag2total.end()) update = false;

        newOne = tag2name.find(tag) == tag2name.end();
        key2tag[Key] = tag;

        if (Format.length()) {
            if (key2tag.find(Name) == key2tag.end()) {
                key2tag[Name] = tag;
            }
            tag2format[tag] = Format;
        }
        tag2name[tag] = Name;

        tag2uid_const_iterator ut = tag2uid.find(tag);
        if (ut != tag2uid.end()) {
            if (uid == AID_ROOT) {
                tag2uid.erase(ut);
                update = true;
            } else if (ut->second.find(uid) == ut->second.end()) {
                const_cast<uid_list&>(ut->second).emplace(uid);
                update = true;
            }
        } else if (newOne && (uid != AID_ROOT)) {
            tag2uid[tag].emplace(uid);
            update = true;
        }

        // updatePersist -> trigger output on modified
        // content, reset tag2total if available
        if (update && (itot != tag2total.end())) tag2total[tag] = 0;
    }

    if (update) {
        WritePersistEventLogTags(tag, uid, source);
    } else if (warn && !newOne && source) {
        // For the files, we want to report dupes.
        android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag,
            Name.c_str(), Format.c_str(), source);
    }
}

// Read the event log tags file, and build up our internal database
void LogTags::ReadFileEventLogTags(const char* filename, bool warn) {
    bool etc = !strcmp(filename, system_event_log_tags);
    bool debug = !etc && !strcmp(filename, debug_event_log_tags);

    if (!etc) {
        RebuildFileEventLogTags(filename, warn);
    }
    std::string content;
    if (android::base::ReadFileToString(filename, &content)) {
        char* cp = (char*) content.c_str();
        char* endp = cp + content.length();

        {
            android::RWLock::AutoRLock writeLock(rwlock);

            file2watermark[filename] = content.length();
        }

        char* lineStart = cp;
        while (cp < endp) {
            if (*cp == '\n') {
                lineStart = cp;
            } else if (lineStart) {
                if (*cp == '#') {
                    /* comment; just scan to end */
                    lineStart = NULL;
                } else if (isdigit(*cp)) {
                    unsigned long Tag = strtoul(cp, &cp, 10);
                    if (warn && (Tag > emptyTag)) {
                        android::prdebug("tag too large %lu", Tag);
                    }
                    while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp;
                    if (cp >= endp) break;
                    if (*cp == '\n') continue;
                    const char* name = cp;
                    /* Determine whether it is a valid tag name [a-zA-Z0-9_] */
                    bool hasAlpha = false;
                    while ((cp < endp) && (isalnum(*cp) || (*cp == '_'))) {
                        if (!isdigit(*cp)) hasAlpha = true;
                        ++cp;
                    }
                    std::string Name(name, cp - name);
#ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT
                    static const size_t maximum_official_tag_name_size = 24;
                    if (warn && (Name.length() > maximum_official_tag_name_size)) {
                       android::prdebug("tag name too long %s", Name.c_str());
                    }
#endif
                    if (hasAlpha && ((cp >= endp) || (*cp == '#') || isspace(*cp))) {
                        if (Tag > emptyTag) {
                            if (*cp != '\n') lineStart = NULL;
                            continue;
                        }
                        while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp;
                        const char* format = cp;
                        uid_t uid = AID_ROOT;
                        while ((cp < endp) && (*cp != '\n')) {
                            if (*cp == '#') {
                                uid = sniffUid(cp, endp);
                                lineStart = NULL;
                                break;
                            }
                            ++cp;
                        }
                        while ((cp > format) && isspace(cp[-1])) {
                            --cp;
                            lineStart = NULL;
                        }
                        std::string Format(format, cp - format);

                        AddEventLogTags((uint32_t)Tag, uid, Name, Format,
                                        filename, warn);
                    } else {
                        if (warn) {
                            android::prdebug("tag name invalid %.*s",
                                             (int)(cp - name + 1), name);
                        }
                        lineStart = NULL;
                    }
                } else if (!isspace(*cp)) break;
            }
            cp++;
        }
    } else if (warn) {
        android::prdebug("Cannot read %s", filename);
    }
}

// Extract a 4-byte value from a byte stream.
static inline uint32_t get4LE(const char* msg)
{
    const uint8_t* src = reinterpret_cast<const uint8_t*>(msg);
    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}

// Additional persistent sources for invented log tags.  Read the
// special pmsg event for log tags, and build up our internal
// database with any found.
void LogTags::ReadPersistEventLogTags() {
    struct logger_list* logger_list = android_logger_list_alloc(
        ANDROID_LOG_RDONLY | ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK,
        0, (pid_t)0);
    if (!logger_list) return;

    struct logger* e = android_logger_open(logger_list, LOG_ID_EVENTS);
    struct logger* s = android_logger_open(logger_list, LOG_ID_SECURITY);
    if (!e && !s) {
        android_logger_list_free(logger_list);
        return;
    }

    for (;;) {
        struct log_msg log_msg;
        int ret = android_logger_list_read(logger_list, &log_msg);
        if (ret <= 0) break;

        const char* msg = log_msg.msg();
        if (!msg) continue;
        if (log_msg.entry.len <= sizeof(uint32_t)) continue;
        uint32_t Tag = get4LE(msg);
        if (Tag != TAG_DEF_LOG_TAG) continue;
        uid_t uid = (log_msg.entry.hdr_size >= sizeof(logger_entry_v4)) ?
            log_msg.entry.uid : AID_ROOT;

        std::string Name;
        std::string Format;
        android_log_list_element elem;
        {
            android_log_event_list ctx(log_msg);
            elem = ctx.read();
            if (elem.type != EVENT_TYPE_LIST) {
                continue;
            }
            elem = ctx.read();
            if (elem.type != EVENT_TYPE_INT) {
                continue;
            }
            Tag = elem.data.int32;
            elem = ctx.read();
            if (elem.type != EVENT_TYPE_STRING) {
                continue;
            }
            Name = std::string(elem.data.string, elem.len);
            elem = ctx.read();
            if (elem.type != EVENT_TYPE_STRING) {
                continue;
            }
            Format = std::string(elem.data.string, elem.len);
            elem = ctx.read();
        }
        if ((elem.type != EVENT_TYPE_LIST_STOP) || !elem.complete) continue;

        AddEventLogTags(Tag, uid, Name, Format);
    }
    android_logger_list_free(logger_list);
}

LogTags::LogTags() {
    ReadFileEventLogTags(system_event_log_tags);
    // Following will likely fail on boot, but is required if logd restarts
    ReadFileEventLogTags(dynamic_event_log_tags, false);
    if (__android_log_is_debuggable()) {
        ReadFileEventLogTags(debug_event_log_tags, false);
    }
    ReadPersistEventLogTags();

    logtags = this;
}

// Converts an event tag into a name
const char* LogTags::tagToName(uint32_t tag) const {
    tag2name_const_iterator it;

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    it = tag2name.find(tag);
    if ((it == tag2name.end()) || (it->second.length() == 0)) return NULL;

    return it->second.c_str();
}

// Prototype in LogUtils.h allowing external access to our database.
//
// This must be a pure reader to our database, as everything else is
// guaranteed single-threaded except this access point which is
// asynchonous and can be multithreaded and thus rentrant.  The
// object's rwlock is only used to guarantee atomic access to the
// unordered_map to prevent corruption, with a requirement to be a
// low chance of contention for this call.  If we end up changing
// this algorithm resulting in write, then we should use a different
// lock than the object's rwlock to protect groups of associated
// actions.
const char* android::tagToName(uint32_t tag) {
    LogTags* me = logtags;

    if (!me) return NULL;
    me->WritePmsgEventLogTags(tag);
    return me->tagToName(tag);
}

// Prototype in LogUtils.h allowing external access to our database.
//
// This only works on userdebug and eng devices to re-read the
// /data/misc/logd/event-log-tags file right after /data is mounted.
// The operation is near to boot and should only happen once.  There
// are races associated with its use since it can trigger a Rebuild
// of the file, but that is a can-not-happen since the file was not
// read yet.  More dangerous if called later, but if all is well it
// should just skip over everything and not write any new entries.
void android::ReReadEventLogTags() {
    LogTags* me = logtags;

    if (me && __android_log_is_debuggable()) {
        me->ReadFileEventLogTags(me->debug_event_log_tags);
    }
}

// converts an event tag into a format
const char* LogTags::tagToFormat(uint32_t tag) const {
    tag2format_const_iterator iform;

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    iform = tag2format.find(tag);
    if (iform == tag2format.end()) return NULL;

    return iform->second.c_str();
}

// converts a name into an event tag
uint32_t LogTags::nameToTag(const char* name) const {
    uint32_t ret = emptyTag;

    // Bug: Only works for a single entry, we can have multiple entries,
    // one for each format, so we find first entry recorded, or entry with
    // no format associated with it.

    android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));

    key2tag_const_iterator ik = key2tag.find(std::string(name));
    if (ik != key2tag.end()) ret = ik->second;

    return ret;
}

// Caller must perform locks, can be under reader (for pre-check) or
// writer lock.  We use this call to invent a new deterministically
// random tag, unique is cleared if no conflicts.  If format is NULL,
// we are in readonly mode.
uint32_t LogTags::nameToTag_locked(const std::string& name,
                                   const char* format,
                                   bool& unique) {
    key2tag_const_iterator ik;

    bool write = format != NULL;
    unique = write;

    if (!write) {
        // Bug: Only works for a single entry, we can have multiple entries,
        // one for each format, so we find first entry recorded, or entry with
        // no format associated with it.
        ik = key2tag.find(name);
        if (ik == key2tag.end()) return emptyTag;
        return ik->second;
    }

    std::string Key(name);
    if (*format) Key += std::string("+") + format;

    ik = key2tag.find(Key);
    if (ik != key2tag.end()) {
        unique = false;
        return ik->second;
    }

    size_t Hash = key2tag.hash_function()(Key);
    uint32_t Tag = Hash;
    // This sets an upper limit on the conflics we are allowed to deal with.
    for (unsigned i = 0; i < 256; ) {
        tag2name_const_iterator it = tag2name.find(Tag);
        if (it == tag2name.end()) return Tag;
        std::string localKey(it->second);
        tag2format_const_iterator iform = tag2format.find(Tag);
        if ((iform == tag2format.end()) && iform->second.length()) {
            localKey += "+" + iform->second;
        }
        unique = !!it->second.compare(localKey);
        if (!unique) return Tag; // unlikely except in a race

        ++i;
        // Algorithm to convert hash to next tag
        if (i < 32) {
            Tag = (Hash >> i);
            // size_t is 32 bits, or upper word zero, rotate
            if ((sizeof(Hash) <= 4) ||
                    ((Hash & (uint64_t(-1LL) << 32)) == 0)) {
                Tag |= Hash << (32 - i);
            }
        } else {
            Tag = Hash + i - 31;
        }
    }
    return emptyTag;
}

static int openFile(const char* name, int mode, bool warning) {
    int fd = TEMP_FAILURE_RETRY(open(name, mode));
    if ((fd < 0) && warning) {
        android::prdebug("Failed open %s (%d)", name, errno);
    }
    return fd;
}

void LogTags::WritePmsgEventLogTags(uint32_t tag, uid_t uid) {
    android::RWLock::AutoRLock readLock(rwlock);

    tag2total_const_iterator itot = tag2total.find(tag);
    if (itot == tag2total.end()) return; // source is a static entry

    size_t lastTotal = itot->second;

    // Every 16K (half the smallest configurable pmsg buffer size) record
    static const size_t rate_to_pmsg = 16 * 1024;
    if (lastTotal && ((android::sizesTotal() - lastTotal) < rate_to_pmsg)) {
        return;
    }

    static int pmsg_fd = -1;
    if (pmsg_fd < 0) {
        pmsg_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
        // unlikely, but deal with partners with borken pmsg
        if (pmsg_fd < 0) return;
    }

    std::string Name = tag2name[tag];
    tag2format_const_iterator iform = tag2format.find(tag);
    std::string Format = (iform != tag2format.end()) ? iform->second : "";

    __android_log_event_list ctx(TAG_DEF_LOG_TAG);
    ctx << tag << Name << Format;
    std::string buffer(ctx);
    if (buffer.length() <= 0) return; // unlikely

    /*
     *  struct {
     *      // what we provide to pstore
     *      android_pmsg_log_header_t pmsgHeader;
     *      // what we provide to file
     *      android_log_header_t header;
     *      // caller provides
     *      union {
     *          struct {
     *              char     prio;
     *              char     payload[];
     *          } string;
     *          struct {
     *              uint32_t tag
     *              char     payload[];
     *          } binary;
     *      };
     *  };
     */

    struct timespec ts;
    clock_gettime(android_log_clockid(), &ts);

    android_log_header_t header = {
        .id = LOG_ID_EVENTS,
        .tid = (uint16_t)gettid(),
        .realtime.tv_sec = (uint32_t)ts.tv_sec,
        .realtime.tv_nsec = (uint32_t)ts.tv_nsec,
    };

    uint32_t outTag = TAG_DEF_LOG_TAG;
    outTag = get4LE((const char*)&outTag);

    android_pmsg_log_header_t pmsgHeader = {
        .magic = LOGGER_MAGIC,
        .len = (uint16_t)(sizeof(pmsgHeader) + sizeof(header) +
                          sizeof(outTag) + buffer.length()),
        .uid = (uint16_t)AID_ROOT,
        .pid = (uint16_t)getpid(),
    };

    struct iovec Vec[] = {
        { (unsigned char*)&pmsgHeader, sizeof(pmsgHeader) },
        { (unsigned char*)&header, sizeof(header) },
        { (unsigned char*)&outTag, sizeof(outTag) },
        { (unsigned char*)const_cast<char*>(buffer.data()), buffer.length() }
    };

    tag2uid_const_iterator ut = tag2uid.find(tag);
    if (ut == tag2uid.end()) {
        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
    } else if (uid != AID_ROOT) {
        pmsgHeader.uid = (uint16_t)uid;
        TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
    } else {
        for (auto &it : ut->second) {
            pmsgHeader.uid = (uint16_t)it;
            TEMP_FAILURE_RETRY(writev(pmsg_fd, Vec, arraysize(Vec)));
        }
    }
}

void LogTags::WriteDynamicEventLogTags(uint32_t tag, uid_t uid) {
    static const int mode = O_WRONLY | O_APPEND |
                            O_CLOEXEC | O_NOFOLLOW | O_BINARY;

    int fd = openFile(dynamic_event_log_tags, mode, true);
    if (fd < 0) return;

    android::RWLock::AutoWLock writeLock(rwlock);

    std::string ret = formatEntry_locked(tag, uid, false);
    android::base::WriteStringToFd(ret, fd);
    TEMP_FAILURE_RETRY(close(fd));

    size_t size = 0;
    file2watermark_const_iterator iwater;

    iwater = file2watermark.find(dynamic_event_log_tags);
    if (iwater != file2watermark.end()) size = iwater->second;

    file2watermark[dynamic_event_log_tags] = size + ret.length();
}

void LogTags::WriteDebugEventLogTags(uint32_t tag, uid_t uid) {
    static const int mode = O_WRONLY | O_APPEND |
                            O_CLOEXEC | O_NOFOLLOW | O_BINARY;

    static bool one = true;
    int fd = openFile(debug_event_log_tags, mode, one);
    one = fd >= 0;
    if (!one) return;

    android::RWLock::AutoWLock writeLock(rwlock);

    std::string ret = formatEntry_locked(tag, uid, false);
    android::base::WriteStringToFd(ret, fd);
    TEMP_FAILURE_RETRY(close(fd));

    size_t size = 0;
    file2watermark_const_iterator iwater;

    iwater = file2watermark.find(debug_event_log_tags);
    if (iwater != file2watermark.end()) size = iwater->second;

    file2watermark[debug_event_log_tags] = size + ret.length();
}

// How we maintain some runtime or reboot stickiness
void LogTags::WritePersistEventLogTags(uint32_t tag,
                                       uid_t uid, const char* source) {
    // very unlikely
    bool etc = source && !strcmp(source, system_event_log_tags);
    if (etc) return;

    bool dynamic = source && !strcmp(source, dynamic_event_log_tags);
    bool debug = (!dynamic &&
                  source &&
                  !strcmp(source, debug_event_log_tags)) ||
                 !__android_log_is_debuggable();

    WritePmsgEventLogTags(tag, uid);

    size_t lastTotal = 0;
    {
        android::RWLock::AutoRLock readLock(rwlock);

        tag2total_const_iterator itot = tag2total.find(tag);
        if (itot != tag2total.end()) lastTotal = itot->second;
    }

    if (lastTotal == 0) { // denotes first time for this one
        if (!dynamic || !RebuildFileEventLogTags(dynamic_event_log_tags)) {
            WriteDynamicEventLogTags(tag, uid);
        }

        if (!debug && !RebuildFileEventLogTags(debug_event_log_tags)) {
            WriteDebugEventLogTags(tag, uid);
        }
    }

    lastTotal = android::sizesTotal();
    if (!lastTotal) ++lastTotal;

    // record totals for next watermark.
    android::RWLock::AutoWLock writeLock(rwlock);
    tag2total[tag] = lastTotal;
}

// nameToTag converts a name into an event tag. If format is NULL, then we
// are in readonly mode.
uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) {
    std::string Name = std::string(name);
    bool write = format != NULL;
    bool updateUid = uid != AID_ROOT;
    bool updateFormat = format && *format;
    bool unique;
    uint32_t Tag;

    {
        android::RWLock::AutoRLock readLock(rwlock);

        Tag = nameToTag_locked(Name, format, unique);
        if (updateUid && (Tag != emptyTag) && !unique) {
            tag2uid_const_iterator ut = tag2uid.find(Tag);
            if (updateUid) {
                if ((ut != tag2uid.end()) &&
                        (ut->second.find(uid) == ut->second.end())) {
                    unique = write; // write passthrough to update uid counts
                    if (!write) Tag = emptyTag; // deny read access
                }
            } else {
                unique = write && (ut != tag2uid.end());
            }
        }
    }

    if (Tag == emptyTag) return Tag;
    WritePmsgEventLogTags(Tag, uid); // record references periodically
    if (!unique) return Tag;

    bool updateWrite = false;
    bool updateTag;

    // Special case of AddEventLogTags, checks per-uid counter which makes
    // no sense there, and is also optimized somewhat to reduce write times.
    {
        android::RWLock::AutoWLock writeLock(rwlock);

        // double check after switch from read lock to write lock for Tag
        updateTag = tag2name.find(Tag) == tag2name.end();
        // unlikely, either update, race inviting conflict or multiple uids
        if (!updateTag) {
            Tag = nameToTag_locked(Name, format, unique);
            if (Tag == emptyTag) return Tag;
            // is it multiple uid's setting this value
            if (!unique) {
                tag2uid_const_iterator ut = tag2uid.find(Tag);
                if (updateUid) {
                    // Add it to the uid list
                    if ((ut == tag2uid.end()) ||
                        (ut->second.find(uid) != ut->second.end())) return Tag;
                    const_cast<uid_list&>(ut->second).emplace(uid);
                    updateWrite = true;
                } else {
                    if (ut == tag2uid.end()) return Tag;
                    // (system) adding a global one, erase the uid list
                    tag2uid.erase(ut);
                    updateWrite = true;
                }
            }
        }

        // Update section
        size_t count;
        if (updateUid) {
            count = 0;
            uid2count_const_iterator ci = uid2count.find(uid);
            if (ci != uid2count.end()) {
                count = ci->second;
                if (count >= max_per_uid) {
                    if (!updateWrite) return emptyTag;
                    // If we are added to the per-Uid perms, leak the Tag
                    // if it already exists.
                    updateUid = false;
                    updateTag = false;
                    updateFormat = false;
                }
            }
        }

        // updateWrite -> trigger output on modified content, reset tag2total
        //    also sets static to dynamic entries if they are alterred,
        //    only occurs if they have a uid, and runtime adds another uid.
        if (updateWrite) tag2total[Tag] = 0;

        if (updateTag) {
            // mark as a dynamic entry, but do not upset current total counter
            tag2total_const_iterator itot = tag2total.find(Tag);
            if (itot == tag2total.end()) tag2total[Tag] = 0;

            if (*format) {
                key2tag[Name + "+" + format] = Tag;
                if (key2tag.find(Name) == key2tag.end()) key2tag[Name] = Tag;
            } else {
                key2tag[Name] = Tag;
            }
            tag2name[Tag] = Name;
        }
        if (updateFormat) tag2format[Tag] = format;

        if (updateUid) {
            tag2uid[Tag].emplace(uid);
            uid2count[uid] = count + 1;
        }
    }

    if (updateTag || updateFormat || updateWrite) {
        WritePersistEventLogTags(Tag, uid);
    }

    return Tag;
}

std::string LogTags::formatEntry(uint32_t tag, uid_t uid,
                                 const char* name,
                                 const char* format) {
    if (!format || !format[0]) {
        return android::base::StringPrintf("%" PRIu32 "\t%s\n", tag, name);
    }
    size_t len = (strlen(name) + 7) / 8;
    static const char tabs[] = "\t\t\t";
    if (len > strlen(tabs)) len = strlen(tabs);
    std::string Uid;
    if (uid != AID_ROOT) Uid = android::base::StringPrintf(" # uid=%u", uid);
    return android::base::StringPrintf("%" PRIu32 "\t%s%s\t%s%s\n",
                                       tag, name, &tabs[len], format,
                                       Uid.c_str());
}

std::string LogTags::formatEntry_locked(uint32_t tag, uid_t uid,
                                        bool authenticate) {
    const char* name = tag2name[tag].c_str();

    const char* format = "";
    tag2format_const_iterator iform = tag2format.find(tag);
    if (iform != tag2format.end()) format = iform->second.c_str();

    // Access permission test, do not report dynamic entries
    // that do not belong to us.
    tag2uid_const_iterator ut = tag2uid.find(tag);
    if (ut == tag2uid.end()) {
        return formatEntry(tag, AID_ROOT, name, format);
    }
    if (uid != AID_ROOT) {
        if (authenticate && (ut->second.find(uid) == ut->second.end())) {
            return std::string("");
        }
        return formatEntry(tag, uid, name, format);
    }

    // Show all, one for each registered uid (we are group root)
    std::string ret;
    for (auto &it : ut->second) {
        ret += formatEntry(tag, it, name, format);
    }
    return ret;
}

std::string LogTags::formatEntry(uint32_t tag, uid_t uid) {
    android::RWLock::AutoRLock readLock(rwlock);
    return formatEntry_locked(tag, uid);
}

std::string LogTags::formatGetEventTag(uid_t uid,
                                       const char* name, const char* format) {
    bool all = name && (name[0] == '*') && !name[1];
    bool list = !name || all;
    std::string ret;

    if (!list) {
        // switch to read entry only if format == "*"
        if (format && (format[0] == '*') && !format[1]) format = NULL;

        // WAI: for null format, only works for a single entry, we can have
        // multiple entries, one for each format, so we find first entry
        // recorded, or entry with no format associated with it.
        // We may desire to print all that match the name, but we did not
        // add a mapping table for that and the cost is too high.
        uint32_t tag = nameToTag(uid, name, format);
        if (tag == emptyTag) return std::string("-1 ESRCH");
        if (uid == AID_ROOT) {
            android::RWLock::AutoRLock readLock(rwlock);

            // first uid in list so as to manufacture an accurate reference
            tag2uid_const_iterator ut = tag2uid.find(tag);
            if ((ut != tag2uid.end()) &&
                 (ut->second.begin() != ut->second.end())) {
                uid = *(ut->second.begin());
            }
        }
        ret = formatEntry(tag, uid, name, format ?: tagToFormat(tag));
        if (!ret.length()) return std::string("-1 ESRCH");
        return ret;
    }

    android::RWLock::AutoRLock readLock(rwlock);
    if (all) {
        // everything under the sun
        for (const auto& it : tag2name) {
            ret += formatEntry_locked(it.first, uid);
        }
    } else {
        // set entries are dynamic
        for (const auto& it : tag2total) {
            ret += formatEntry_locked(it.first, uid);
        }
    }
    return ret;
}
