_ZN11ArgsManagerD2Ev:
  130|      2|ArgsManager::~ArgsManager() = default;

_ZN15ChaCha20AlignedD2Ev:
   42|      4|{
   43|      4|    memory_cleanse(input, sizeof(input));
   44|      4|}
_ZN8ChaCha20D2Ev:
  332|      4|{
  333|      4|    memory_cleanse(m_buffer.data(), m_buffer.size());
  334|      4|}

_ZN9ChainCodeD2Ev:
   28|      2|    ~ChainCode() { memory_cleanse(data(), size()); }

_ZN11CNetCleanupD2Ev:
 3676|      2|    {
 3677|       |#ifdef WIN32
 3678|       |        // Shutdown Windows Sockets
 3679|       |        WSACleanup();
 3680|       |#endif
 3681|      2|    }

_ZNK9prevectorILj16EhjiE9is_directEv:
  126|     16|    bool is_direct() const { return _size <= N; }
_ZN9prevectorILj16EhjiED2Ev:
  422|     16|    ~prevector() {
  423|     16|        if (!is_direct()) {
  ------------------
  |  Branch (423:13): [True: 0, False: 16]
  ------------------
  424|      0|            free(_union.indirect_contents.indirect);
  425|      0|            _union.indirect_contents.indirect = nullptr;
  426|      0|        }
  427|     16|    }
_ZNK9prevectorILj36EhjiE9is_directEv:
  126|     14|    bool is_direct() const { return _size <= N; }
_ZN9prevectorILj36EhjiED2Ev:
  422|     14|    ~prevector() {
  423|     14|        if (!is_direct()) {
  ------------------
  |  Branch (423:13): [True: 0, False: 14]
  ------------------
  424|      0|            free(_union.indirect_contents.indirect);
  425|      0|            _union.indirect_contents.indirect = nullptr;
  426|      0|        }
  427|     14|    }

random.cpp:_ZN12_GLOBAL__N_18RNGStateD2Ev:
  367|      2|    ~RNGState() = default;

_ZN20BaseSignatureCheckerD2Ev:
  298|      2|    virtual ~BaseSignatureChecker() = default;

_ZN20BaseSignatureCreatorD2Ev:
   41|      4|    virtual ~BaseSignatureCreator() = default;

_ZN15SigningProviderD2Ev:
  170|      2|    virtual ~SigningProvider() = default;

random.cpp:_ZN16secure_allocatorIN12_GLOBAL__N_18RNGStateEE10deallocateEPS1_m:
   37|      2|    {
   38|      2|        if (p != nullptr) {
  ------------------
  |  Branch (38:13): [True: 2, False: 0]
  ------------------
   39|      2|            memory_cleanse(p, sizeof(T) * n);
   40|      2|        }
   41|      2|        LockedPoolManager::Instance().free(p);
   42|      2|    }

_Z14memory_cleansePvm:
   15|     14|{
   16|       |#if defined(WIN32)
   17|       |    /* SecureZeroMemory is guaranteed not to be optimized out. */
   18|       |    SecureZeroMemory(ptr, len);
   19|       |#else
   20|     14|    std::memset(ptr, 0, len);
   21|       |
   22|       |    /* Memory barrier that scares the compiler away from optimizing out the memset.
   23|       |     *
   24|       |     * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
   25|       |     * in BoringSSL (ISC License):
   26|       |     *    As best as we can tell, this is sufficient to break any optimisations that
   27|       |     *    might try to eliminate "superfluous" memsets.
   28|       |     * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
   29|       |     * is pretty efficient because the compiler can still implement the memset() efficiently,
   30|       |     * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
   31|       |     * Yang et al. (USENIX Security 2017) for more background.
   32|       |     */
   33|     14|    __asm__ __volatile__("" : : "r"(ptr) : "memory");
   34|     14|#endif
   35|     14|}

_ZN5ArenaD2Ev:
   48|      2|Arena::~Arena() = default;
_ZN5Arena4freeEPv:
   87|      2|{
   88|       |    // Freeing the nullptr pointer is OK.
   89|      2|    if (ptr == nullptr) {
  ------------------
  |  Branch (89:9): [True: 0, False: 2]
  ------------------
   90|      0|        return;
   91|      0|    }
   92|       |
   93|       |    // Remove chunk from used map
   94|      2|    auto i = chunks_used.find(ptr);
   95|      2|    if (i == chunks_used.end()) {
  ------------------
  |  Branch (95:9): [True: 0, False: 2]
  ------------------
   96|      0|        throw std::runtime_error("Arena: invalid or double free");
   97|      0|    }
   98|      2|    auto freed = std::make_pair(static_cast<char*>(i->first), i->second);
   99|      2|    chunks_used.erase(i);
  100|       |
  101|       |    // coalesce freed with previous chunk
  102|      2|    auto prev = chunks_free_end.find(freed.first);
  103|      2|    if (prev != chunks_free_end.end()) {
  ------------------
  |  Branch (103:9): [True: 2, False: 0]
  ------------------
  104|      2|        freed.first -= prev->second->first;
  105|      2|        freed.second += prev->second->first;
  106|      2|        size_to_free_chunk.erase(prev->second);
  107|      2|        chunks_free_end.erase(prev);
  108|      2|    }
  109|       |
  110|       |    // coalesce freed with chunk after freed
  111|      2|    auto next = chunks_free.find(freed.first + freed.second);
  112|      2|    if (next != chunks_free.end()) {
  ------------------
  |  Branch (112:9): [True: 0, False: 2]
  ------------------
  113|      0|        freed.second += next->second->first;
  114|      0|        size_to_free_chunk.erase(next->second);
  115|      0|        chunks_free.erase(next);
  116|      0|    }
  117|       |
  118|       |    // Add/set space with coalesced free chunk
  119|      2|    auto it = size_to_free_chunk.emplace(freed.second, freed.first);
  120|      2|    chunks_free[freed.first] = it;
  121|      2|    chunks_free_end[freed.first + freed.second] = it;
  122|      2|}
_ZN24PosixLockedPageAllocator10FreeLockedEPvm:
  254|      2|{
  255|      2|    len = align_up(len, page_size);
  256|      2|    memory_cleanse(addr, len);
  257|      2|    munlock(addr, len);
  258|      2|    munmap(addr, len);
  259|      2|}
_ZN10LockedPoolD2Ev:
  283|      2|LockedPool::~LockedPool() = default;
_ZN10LockedPool4freeEPv:
  308|      2|{
  309|      2|    std::lock_guard<std::mutex> lock(mutex);
  310|       |    // TODO we can do better than this linear search by keeping a map of arena
  311|       |    // extents to arena, and looking up the address.
  312|      2|    for (auto &arena: arenas) {
  ------------------
  |  Branch (312:21): [True: 2, False: 0]
  ------------------
  313|      2|        if (arena.addressInArena(ptr)) {
  ------------------
  |  Branch (313:13): [True: 2, False: 0]
  ------------------
  314|      2|            arena.free(ptr);
  315|      2|            return;
  316|      2|        }
  317|      2|    }
  318|      0|    throw std::runtime_error("LockedPool: invalid address not pointing to any arena");
  319|      2|}
_ZN10LockedPool15LockedPageArenaD2Ev:
  370|      2|{
  371|      2|    allocator->FreeLocked(base, size);
  372|      2|}
_ZN17LockedPoolManager8InstanceEv:
  405|      2|{
  406|      2|    static std::once_flag init_flag;
  407|      2|    std::call_once(init_flag, LockedPoolManager::CreateInstance);
  408|      2|    return *LockedPoolManager::_instance;
  409|      2|}
lockedpool.cpp:_ZL8align_upmm:
   32|      2|{
   33|      2|    return (x + align - 1) & ~(align - 1);
   34|      2|}

_ZNK5Arena14addressInArenaEPv:
   90|      2|    bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; }
  ------------------
  |  Branch (90:51): [True: 2, False: 0]
  |  Branch (90:66): [True: 2, False: 0]
  ------------------
_ZN19LockedPageAllocatorD2Ev:
   22|      2|    virtual ~LockedPageAllocator() = default;

_ZN14AnnotatedMixinINSt3__115recursive_mutexEED2Ev:
   96|      2|    ~AnnotatedMixin() {
   97|      2|        DeleteLock((void*)this);
   98|      2|    }
_ZN14AnnotatedMixinINSt3__15mutexEED2Ev:
   96|     64|    ~AnnotatedMixin() {
   97|     64|        DeleteLock((void*)this);
   98|     64|    }
_Z10DeleteLockPv:
   74|     66|inline void DeleteLock(void* cs) {}
_Z17MaybeCheckNotHeldR14AnnotatedMixinINSt3__15mutexEE:
  258|     30|inline Mutex& MaybeCheckNotHeld(Mutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; }
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEEC2ERS3_PKcS7_ib:
  181|     30|    UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock)
  182|     30|    {
  183|     30|        if (fTry)
  ------------------
  |  Branch (183:13): [True: 0, False: 30]
  ------------------
  184|      0|            TryEnter(pszName, pszFile, nLine);
  185|     30|        else
  186|     30|            Enter(pszName, pszFile, nLine);
  187|     30|    }
_Z13EnterCriticalINSt3__15mutexEEvPKcS3_iPT_b:
   67|     30|inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {}
_Z13LeaveCriticalv:
   68|     30|inline void LeaveCritical() {}
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEE5EnterEPKcS6_i:
  159|     30|    {
  160|     30|        EnterCritical(pszName, pszFile, nLine, Base::mutex());
  161|       |#ifdef DEBUG_LOCKCONTENTION
  162|       |        if (!Base::try_lock()) {
  163|       |            ContendedLock(pszName, pszFile, nLine, static_cast<Base&>(*this));
  164|       |        }
  165|       |#else
  166|     30|        Base::lock();
  167|     30|#endif
  168|     30|    }
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEED2Ev:
  201|     30|    {
  202|     30|        if (Base::owns_lock())
  ------------------
  |  Branch (202:13): [True: 30, False: 0]
  ------------------
  203|     30|            LeaveCritical();
  204|     30|    }

_Z11BitsToBytesNSt3__14spanIKhLm18446744073709551615EEE:
   16|  97.0k|{
   17|  97.0k|    std::vector<std::byte> ret;
   18|  97.0k|    uint8_t next_byte{0};
   19|  97.0k|    int next_byte_bits{0};
   20|   111M|    for (uint8_t val : bits) {
  ------------------
  |  Branch (20:22): [True: 111M, False: 97.0k]
  ------------------
   21|   111M|        next_byte |= (val & 1) << (next_byte_bits++);
   22|   111M|        if (next_byte_bits == 8) {
  ------------------
  |  Branch (22:13): [True: 13.8M, False: 97.5M]
  ------------------
   23|  13.8M|            ret.push_back(std::byte(next_byte));
   24|  13.8M|            next_byte = 0;
   25|  13.8M|            next_byte_bits = 0;
   26|  13.8M|        }
   27|   111M|    }
   28|  97.0k|    if (next_byte_bits) ret.push_back(std::byte(next_byte));
  ------------------
  |  Branch (28:9): [True: 84.9k, False: 12.0k]
  ------------------
   29|       |
   30|  97.0k|    return ret;
   31|  97.0k|}
_Z24asmap_direct_fuzz_targetNSt3__14spanIKhLm18446744073709551615EEE:
   34|    732|{
   35|       |    // Encoding: [asmap using 1 bit / byte] 0xFF [addr using 1 bit / byte]
   36|    732|    std::optional<size_t> sep_pos_opt;
   37|  21.7M|    for (size_t pos = 0; pos < buffer.size(); ++pos) {
  ------------------
  |  Branch (37:26): [True: 21.7M, False: 709]
  ------------------
   38|  21.7M|        uint8_t x = buffer[pos];
   39|  21.7M|        if ((x & 0xFE) == 0) continue;
  ------------------
  |  Branch (39:13): [True: 21.7M, False: 727]
  ------------------
   40|    727|        if (x == 0xFF) {
  ------------------
  |  Branch (40:13): [True: 708, False: 19]
  ------------------
   41|    708|            if (sep_pos_opt) return;
  ------------------
  |  Branch (41:17): [True: 4, False: 704]
  ------------------
   42|    704|            sep_pos_opt = pos;
   43|    704|        } else {
   44|     19|            return;
   45|     19|        }
   46|    727|    }
   47|    709|    if (!sep_pos_opt) return; // Needs exactly 1 separator
  ------------------
  |  Branch (47:9): [True: 9, False: 700]
  ------------------
   48|    700|    const size_t sep_pos{sep_pos_opt.value()};
   49|    700|    const size_t ip_len{buffer.size() - sep_pos - 1};
   50|    700|    if (ip_len > 128) return; // At most 128 bits in IP address
  ------------------
  |  Branch (50:9): [True: 14, False: 686]
  ------------------
   51|       |
   52|       |    // Checks on asmap
   53|    686|    auto asmap = BitsToBytes(buffer.first(sep_pos));
   54|    686|    if (SanityCheckAsmap(asmap, ip_len)) {
  ------------------
  |  Branch (54:9): [True: 311, False: 375]
  ------------------
   55|       |        // Verify that for valid asmaps, no prefix (except up to 7 zero padding bits) is valid.
   56|  96.3k|        for (size_t prefix_len = sep_pos - 1; prefix_len > 0; --prefix_len) {
  ------------------
  |  Branch (56:47): [True: 96.0k, False: 311]
  ------------------
   57|  96.0k|            auto prefix = BitsToBytes(buffer.first(prefix_len));
   58|       |            // We have to skip the prefixes of the same length as the original
   59|       |            // asmap, since they will contain some zero padding bits in the last
   60|       |            // byte.
   61|  96.0k|            if (prefix.size() == asmap.size()) continue;
  ------------------
  |  Branch (61:17): [True: 267, False: 95.7k]
  ------------------
   62|  96.0k|            assert(!SanityCheckAsmap(prefix, ip_len));
  ------------------
  |  Branch (62:13): [True: 95.7k, False: 0]
  ------------------
   63|  95.7k|        }
   64|       |
   65|       |        // No address input should trigger assertions in interpreter
   66|    311|        auto addr = BitsToBytes(buffer.subspan(sep_pos + 1));
   67|    311|        (void)Interpret(asmap, addr);
   68|    311|    }
   69|    686|}

LLVMFuzzerTestOneInput:
  213|    732|{
  214|    732|    test_one_input({data, size});
  215|    732|    return 0;
  216|    732|}
fuzz.cpp:_ZL14test_one_inputNSt3__14spanIKhLm18446744073709551615EEE:
   84|    732|{
   85|    732|    CheckGlobals check{};
   86|    732|    (*Assert(g_test_one_input))(buffer);
  ------------------
  |  |  116|    732|#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
  ------------------
   87|    732|}

_ZN12CheckGlobalsC2Ev:
   59|    732|CheckGlobals::CheckGlobals() : m_impl(std::make_unique<CheckGlobalsImpl>()) {}
_ZN12CheckGlobalsD2Ev:
   60|    734|CheckGlobals::~CheckGlobals() = default;
_ZN16CheckGlobalsImplC2Ev:
   17|    732|    {
   18|    732|        g_used_g_prng = false;
   19|    732|        g_seeded_g_prng_zero = false;
   20|    732|        g_used_system_time = false;
   21|    732|        SetMockTime(0s);
   22|    732|        MockableSteadyClock::ClearMockTime();
   23|    732|    }
_ZN16CheckGlobalsImplD2Ev:
   25|    734|    {
   26|    734|        if (g_used_g_prng && !g_seeded_g_prng_zero) {
  ------------------
  |  Branch (26:13): [True: 0, False: 734]
  |  Branch (26:30): [True: 0, False: 0]
  ------------------
   27|      0|            std::cerr << "\n\n"
   28|      0|                         "The current fuzz target used the global random state.\n\n"
   29|       |
   30|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   31|      0|                         "SeedRandomStateForTest(SeedRand::ZEROS) in the first line \n"
   32|      0|                         "of the FUZZ_TARGET function.\n\n"
   33|       |
   34|      0|                         "An alternative solution would be to avoid any use of globals.\n\n"
   35|       |
   36|      0|                         "Without a solution, fuzz instability and non-determinism can lead \n"
   37|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   38|      0|                      << std::endl;
   39|      0|            std::abort(); // Abort, because AFL may try to recover from a std::exit
   40|      0|        }
   41|       |
   42|    734|        if (g_used_system_time) {
  ------------------
  |  Branch (42:13): [True: 0, False: 734]
  ------------------
   43|      0|            std::cerr << "\n\n"
   44|      0|                         "The current fuzz target accessed system time.\n\n"
   45|       |
   46|      0|                         "This is acceptable, but requires the fuzz target to use \n"
   47|      0|                         "a FakeNodeClock, FakeSteadyClock or call \n"
   48|      0|                         "SetMockTime() at the \n" "beginning of processing the \n"
   49|      0|                         "fuzz input.\n\n"
   50|       |
   51|      0|                         "Without setting mock time, time-dependent behavior can lead \n"
   52|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   53|      0|                      << std::endl;
   54|      0|            std::abort();
   55|      0|        }
   56|    734|    }

__gcov_reset:
   13|      2|extern "C" __attribute__((weak)) void __gcov_reset(void) {}

_ZN9base_blobILj256EE4dataEv:
   99|      2|    constexpr unsigned char* data() { return m_data.data(); }
_ZN9base_blobILj256EE4sizeEv:
  107|      2|    static constexpr unsigned int size() { return WIDTH; }

_Z9InterpretNSt3__14spanIKSt4byteLm18446744073709551615EEES3_:
  181|    311|{
  182|    311|    size_t pos{0};
  183|    311|    const size_t endpos{asmap.size() * 8};
  184|    311|    uint8_t ip_bit{0};
  185|    311|    const uint8_t ip_bits_end = ip.size() * 8;
  186|    311|    uint32_t default_asn = 0;
  187|  1.65k|    while (pos < endpos) {
  ------------------
  |  Branch (187:12): [True: 1.65k, False: 0]
  ------------------
  188|  1.65k|        Instruction opcode = DecodeType(pos, asmap);
  189|  1.65k|        if (opcode == Instruction::RETURN) {
  ------------------
  |  Branch (189:13): [True: 224, False: 1.43k]
  ------------------
  190|       |            // Found leaf node - return the ASN
  191|    224|            uint32_t asn = DecodeASN(pos, asmap);
  192|    224|            if (asn == INVALID) break; // ASN straddles EOF
  ------------------
  |  Branch (192:17): [True: 0, False: 224]
  ------------------
  193|    224|            return asn;
  194|  1.43k|        } else if (opcode == Instruction::JUMP) {
  ------------------
  |  Branch (194:20): [True: 402, False: 1.03k]
  ------------------
  195|       |            // Binary branch: if IP bit is 1, jump forward; else continue
  196|    402|            uint32_t jump = DecodeJump(pos, asmap);
  197|    402|            if (jump == INVALID) break; // Jump offset straddles EOF
  ------------------
  |  Branch (197:17): [True: 0, False: 402]
  ------------------
  198|    402|            if (ip_bit == ip_bits_end) break; // No input bits left
  ------------------
  |  Branch (198:17): [True: 0, False: 402]
  ------------------
  199|    402|            if (int64_t{jump} >= static_cast<int64_t>(endpos - pos)) break; // Jumping past EOF
  ------------------
  |  Branch (199:17): [True: 0, False: 402]
  ------------------
  200|    402|            if (ConsumeBitBE(ip_bit, ip)) {  // Check next IP bit (big-endian)
  ------------------
  |  Branch (200:17): [True: 270, False: 132]
  ------------------
  201|    270|                pos += jump;  // Bit = 1: skip to right subtree
  202|    270|            }
  203|       |            // Bit = 0: fall through to left subtree
  204|  1.03k|        } else if (opcode == Instruction::MATCH) {
  ------------------
  |  Branch (204:20): [True: 553, False: 478]
  ------------------
  205|       |            // Compare multiple IP bits against a pattern
  206|       |            // The match value encodes both length and pattern:
  207|       |            // - highest set bit position determines length (bit_width - 1)
  208|       |            // - lower bits contain the pattern to compare
  209|    553|            uint32_t match = DecodeMatch(pos, asmap);
  210|    553|            if (match == INVALID) break; // Match bits straddle EOF
  ------------------
  |  Branch (210:17): [True: 0, False: 553]
  ------------------
  211|    553|            int matchlen = std::bit_width(match) - 1;  // An n-bit value matches n-1 input bits
  212|    553|            if ((ip_bits_end - ip_bit) < matchlen) break; // Not enough input bits
  ------------------
  |  Branch (212:17): [True: 0, False: 553]
  ------------------
  213|  1.31k|            for (int bit = 0; bit < matchlen; bit++) {
  ------------------
  |  Branch (213:31): [True: 853, False: 466]
  ------------------
  214|    853|                if (ConsumeBitBE(ip_bit, ip) != ((match >> (matchlen - 1 - bit)) & 1)) {
  ------------------
  |  Branch (214:21): [True: 87, False: 766]
  ------------------
  215|     87|                    return default_asn;  // Pattern mismatch - use default
  216|     87|                }
  217|    853|            }
  218|       |            // Pattern matched - continue execution
  219|    553|        } else if (opcode == Instruction::DEFAULT) {
  ------------------
  |  Branch (219:20): [True: 478, False: 0]
  ------------------
  220|       |            // Update the default ASN for subsequent MATCH failures
  221|    478|            default_asn = DecodeASN(pos, asmap);
  222|    478|            if (default_asn == INVALID) break; // ASN straddles EOF
  ------------------
  |  Branch (222:17): [True: 0, False: 478]
  ------------------
  223|    478|        } else {
  224|      0|            break; // Instruction straddles EOF
  225|      0|        }
  226|  1.65k|    }
  227|       |    // Reached EOF without RETURN, or aborted (see any of the breaks above)
  228|       |    // - should have been caught by SanityCheckAsmap below
  229|    311|    assert(false);
  ------------------
  |  Branch (229:5): [Folded, False: 0]
  ------------------
  230|      0|    return 0; // 0 is not a valid ASN
  231|      0|}
_Z16SanityCheckAsmapNSt3__14spanIKSt4byteLm18446744073709551615EEEi:
  238|  96.4k|{
  239|  96.4k|    size_t pos{0};
  240|  96.4k|    const size_t endpos{asmap.size() * 8};
  241|  96.4k|    std::vector<std::pair<uint32_t, int>> jumps; // All future positions we may jump to (bit offset in asmap -> bits to consume left)
  242|  96.4k|    jumps.reserve(bits);
  243|  96.4k|    Instruction prevopcode = Instruction::JUMP;
  244|  96.4k|    bool had_incomplete_match = false;  // Track <8 bit matches for efficiency check
  245|       |
  246|  5.73M|    while (pos != endpos) {
  ------------------
  |  Branch (246:12): [True: 5.72M, False: 2.96k]
  ------------------
  247|       |        // There was a jump into the middle of the previous instruction
  248|  5.72M|        if (!jumps.empty() && pos >= jumps.back().first) return false;
  ------------------
  |  Branch (248:13): [True: 2.04M, False: 3.67M]
  |  Branch (248:31): [True: 11, False: 2.04M]
  ------------------
  249|       |
  250|  5.72M|        Instruction opcode = DecodeType(pos, asmap);
  251|  5.72M|        if (opcode == Instruction::RETURN) {
  ------------------
  |  Branch (251:13): [True: 2.03M, False: 3.69M]
  ------------------
  252|       |            // There should not be any RETURN immediately after a DEFAULT (could be combined into just RETURN)
  253|  2.03M|            if (prevopcode == Instruction::DEFAULT) return false;
  ------------------
  |  Branch (253:17): [True: 4.18k, False: 2.02M]
  ------------------
  254|  2.02M|            uint32_t asn = DecodeASN(pos, asmap);
  255|  2.02M|            if (asn == INVALID) return false; // ASN straddles EOF
  ------------------
  |  Branch (255:17): [True: 14.5k, False: 2.01M]
  ------------------
  256|  2.01M|            if (jumps.empty()) {
  ------------------
  |  Branch (256:17): [True: 373, False: 2.01M]
  ------------------
  257|       |                // Nothing to execute anymore
  258|    373|                if (endpos - pos > 7) return false; // Excessive padding
  ------------------
  |  Branch (258:21): [True: 60, False: 313]
  ------------------
  259|  1.29k|                while (pos != endpos) {
  ------------------
  |  Branch (259:24): [True: 984, False: 311]
  ------------------
  260|    984|                    if (ConsumeBitLE(pos, asmap)) return false; // Nonzero padding bit
  ------------------
  |  Branch (260:25): [True: 2, False: 982]
  ------------------
  261|    984|                }
  262|    311|                return true; // Sanely reached EOF
  263|  2.01M|            } else {
  264|       |                // Continue by pretending we jumped to the next instruction
  265|  2.01M|                if (pos != jumps.back().first) return false; // Unreachable code
  ------------------
  |  Branch (265:21): [True: 37, False: 2.01M]
  ------------------
  266|  2.01M|                bits = jumps.back().second; // Restore the number of bits we would have had left after this jump
  267|  2.01M|                jumps.pop_back();
  268|  2.01M|                prevopcode = Instruction::JUMP;
  269|  2.01M|            }
  270|  3.69M|        } else if (opcode == Instruction::JUMP) {
  ------------------
  |  Branch (270:20): [True: 2.05M, False: 1.63M]
  ------------------
  271|  2.05M|            uint32_t jump = DecodeJump(pos, asmap);
  272|  2.05M|            if (jump == INVALID) return false; // Jump offset straddles EOF
  ------------------
  |  Branch (272:17): [True: 7.36k, False: 2.04M]
  ------------------
  273|  2.04M|            if (int64_t{jump} > static_cast<int64_t>(endpos - pos)) return false; // Jump out of range
  ------------------
  |  Branch (273:17): [True: 35.1k, False: 2.01M]
  ------------------
  274|  2.01M|            if (bits == 0) return false; // Consuming bits past the end of the input
  ------------------
  |  Branch (274:17): [True: 35, False: 2.01M]
  ------------------
  275|  2.01M|            --bits;
  276|  2.01M|            uint32_t jump_offset = pos + jump;
  277|  2.01M|            if (!jumps.empty() && jump_offset >= jumps.back().first) return false; // Intersecting jumps
  ------------------
  |  Branch (277:17): [True: 29.2k, False: 1.98M]
  |  Branch (277:35): [True: 28, False: 29.2k]
  ------------------
  278|  2.01M|            jumps.emplace_back(jump_offset, bits);  // Queue jump target for validation
  279|  2.01M|            prevopcode = Instruction::JUMP;
  280|  2.01M|        } else if (opcode == Instruction::MATCH) {
  ------------------
  |  Branch (280:20): [True: 409k, False: 1.22M]
  ------------------
  281|   409k|            uint32_t match = DecodeMatch(pos, asmap);
  282|   409k|            if (match == INVALID) return false; // Match bits straddle EOF
  ------------------
  |  Branch (282:17): [True: 1.77k, False: 407k]
  ------------------
  283|   407k|            int matchlen = std::bit_width(match) - 1;
  284|   407k|            if (prevopcode != Instruction::MATCH) had_incomplete_match = false;
  ------------------
  |  Branch (284:17): [True: 396k, False: 11.3k]
  ------------------
  285|       |            // Within a sequence of matches only at most one should be incomplete
  286|   407k|            if (matchlen < 8 && had_incomplete_match) return false;
  ------------------
  |  Branch (286:17): [True: 400k, False: 7.00k]
  |  Branch (286:33): [True: 495, False: 400k]
  ------------------
  287|   407k|            had_incomplete_match = (matchlen < 8);
  288|   407k|            if (bits < matchlen) return false; // Consuming bits past the end of the input
  ------------------
  |  Branch (288:17): [True: 25, False: 407k]
  ------------------
  289|   407k|            bits -= matchlen;
  290|   407k|            prevopcode = Instruction::MATCH;
  291|  1.22M|        } else if (opcode == Instruction::DEFAULT) {
  ------------------
  |  Branch (291:20): [True: 1.22M, False: 706]
  ------------------
  292|       |            // There should not be two successive DEFAULTs (they could be combined into one)
  293|  1.22M|            if (prevopcode == Instruction::DEFAULT) return false;
  ------------------
  |  Branch (293:17): [True: 2, False: 1.22M]
  ------------------
  294|  1.22M|            uint32_t asn = DecodeASN(pos, asmap);
  295|  1.22M|            if (asn == INVALID) return false; // ASN straddles EOF
  ------------------
  |  Branch (295:17): [True: 28.7k, False: 1.19M]
  ------------------
  296|  1.19M|            prevopcode = Instruction::DEFAULT;
  297|  1.19M|        } else {
  298|    706|            return false; // Instruction straddles EOF
  299|    706|        }
  300|  5.72M|    }
  301|  2.96k|    return false; // Reached EOF without RETURN instruction
  302|  96.4k|}
asmap.cpp:_ZN12_GLOBAL__N_110DecodeTypeERmNSt3__14spanIKSt4byteLm18446744073709551615EEE:
  142|  5.72M|{
  143|  5.72M|    return Instruction(DecodeBits(bitpos, data, 0, TYPE_BIT_SIZES));
  144|  5.72M|}
asmap.cpp:_ZN12_GLOBAL__N_110DecodeBitsERmNSt3__14spanIKSt4byteLm18446744073709551615EEEhNS2_IKhLm18446744073709551615EEE:
   86|  11.4M|{
   87|  11.4M|    uint32_t val = minval;  // Start with minimum encodable value
   88|  11.4M|    bool bit;
   89|  25.5M|    for (auto bit_sizes_it = bit_sizes.begin(); bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
  ------------------
  |  Branch (89:49): [True: 25.5M, False: 0]
  ------------------
   90|       |        // Read continuation bit to determine if we're in this class
   91|  25.5M|        if (bit_sizes_it + 1 != bit_sizes.end()) {  // Unless we're in the last class
  ------------------
  |  Branch (91:13): [True: 23.6M, False: 1.96M]
  ------------------
   92|  23.6M|            if (bitpos >= data.size() * 8) break;
  ------------------
  |  Branch (92:17): [True: 5.15k, False: 23.5M]
  ------------------
   93|  23.5M|            bit = ConsumeBitLE(bitpos, data);
   94|  23.5M|        } else {
   95|  1.96M|            bit = 0;  // Last class has no continuation bit
   96|  1.96M|        }
   97|  25.5M|        if (bit) {
  ------------------
  |  Branch (97:13): [True: 14.1M, False: 11.4M]
  ------------------
   98|       |            // If the value will not fit in this class, subtract its range from val,
   99|       |            // emit a "1" bit and continue with the next class
  100|  14.1M|            val += (1 << *bit_sizes_it);  // Add size of this class
  101|  14.1M|        } else {
  102|       |            // Decode the position within this class in big endian
  103|  80.9M|            for (int b = 0; b < *bit_sizes_it; b++) {
  ------------------
  |  Branch (103:29): [True: 69.5M, False: 11.4M]
  ------------------
  104|  69.5M|                if (bitpos >= data.size() * 8) return INVALID; // Reached EOF in mantissa
  ------------------
  |  Branch (104:21): [True: 48.0k, False: 69.4M]
  ------------------
  105|  69.4M|                bit = ConsumeBitLE(bitpos, data);
  106|  69.4M|                val += bit << (*bit_sizes_it - 1 - b); // Big-endian within the class
  107|  69.4M|            }
  108|  11.4M|            return val;
  109|  11.4M|        }
  110|  25.5M|    }
  111|  5.15k|    return INVALID; // Reached EOF in exponent
  112|  11.4M|}
asmap.cpp:_ZN12_GLOBAL__N_19DecodeASNERmNSt3__14spanIKSt4byteLm18446744073709551615EEE:
  151|  3.25M|{
  152|  3.25M|    return DecodeBits(bitpos, data, 1, ASN_BIT_SIZES);
  153|  3.25M|}
asmap.cpp:_ZN12_GLOBAL__N_110DecodeJumpERmNSt3__14spanIKSt4byteLm18446744073709551615EEE:
  167|  2.05M|{
  168|  2.05M|    return DecodeBits(bitpos, data, 17, JUMP_BIT_SIZES);
  169|  2.05M|}
asmap.cpp:_ZN12_GLOBAL__N_112ConsumeBitBEERhNSt3__14spanIKSt4byteLm18446744073709551615EEE:
   64|  1.25k|{
   65|  1.25k|    const bool bit = (std::to_integer<uint8_t>(bytes[bitpos / 8]) >> (7 - (bitpos % 8))) & 1;
   66|  1.25k|    ++bitpos;
   67|  1.25k|    return bit;
   68|  1.25k|}
asmap.cpp:_ZN12_GLOBAL__N_111DecodeMatchERmNSt3__14spanIKSt4byteLm18446744073709551615EEE:
  159|   409k|{
  160|   409k|    return DecodeBits(bitpos, data, 2, MATCH_BIT_SIZES);
  161|   409k|}
asmap.cpp:_ZN12_GLOBAL__N_112ConsumeBitLEERmNSt3__14spanIKSt4byteLm18446744073709551615EEE:
   53|  93.0M|{
   54|  93.0M|    const bool bit = (std::to_integer<uint8_t>(bytes[bitpos / 8]) >> (bitpos % 8)) & 1;
   55|  93.0M|    ++bitpos;
   56|  93.0M|    return bit;
   57|  93.0M|}

_ZN10btcsignals6signalIFvvENS_10null_valueEED2Ev:
  175|      6|    ~signal() = default;
_ZN10btcsignals6signalIFv20SynchronizationStatellbENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFv20SynchronizationStateRK11CBlockIndexdENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEibENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvbENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFviENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFbRK13bilingual_strRKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEjENS_6any_ofEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRK13bilingual_strjENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;

_Z22inline_assertion_checkILb1ERPKNSt3__18functionIFvNS0_4spanIKhLm18446744073709551615EEEEEEEOT0_SB_RKNS0_15source_locationENS0_17basic_string_viewIcNS0_11char_traitsIcEEEE:
   90|    732|{
   91|    732|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [True: 732, Folded]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|    732|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 732]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|    732|    }
   96|    732|    return std::forward<T>(val);
   97|    732|}
_Z22inline_assertion_checkILb1EbEOT0_S1_RKNSt3__115source_locationENS2_17basic_string_viewIcNS2_11char_traitsIcEEEE:
   90|    732|{
   91|    732|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [True: 732, Folded]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|    732|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 732]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|    732|    }
   96|    732|    return std::forward<T>(val);
   97|    732|}
_Z22inline_assertion_checkILb0EbEOT0_S1_RKNSt3__115source_locationENS2_17basic_string_viewIcNS2_11char_traitsIcEEEE:
   90|     10|{
   91|     10|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [Folded, False: 0]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|     10|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 10]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|     10|    }
   96|     10|    return std::forward<T>(val);
   97|     10|}

_ZN16CThreadInterruptD2Ev:
   32|      4|    virtual ~CThreadInterrupt() = default;

_ZN10ThreadPoolD2Ev:
   93|     10|    {
   94|     10|        Stop(); // In case it hasn't been stopped.
   95|     10|    }
_ZN10ThreadPool4StopEv:
  129|     10|    {
  130|       |        // Notify workers and join them
  131|     10|        std::vector<std::thread> threads_to_join;
  132|     10|        {
  133|     10|            LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  134|       |            // Ensure Stop() is not called from a worker thread while workers are still registered,
  135|       |            // otherwise a self-join deadlock would occur.
  136|     10|            auto id = std::this_thread::get_id();
  137|     10|            for (const auto& worker : m_workers) assert(worker.get_id() != id);
  ------------------
  |  Branch (137:37): [True: 0, False: 10]
  |  Branch (137:50): [True: 0, False: 0]
  ------------------
  138|       |            // Early shutdown to return right away on any concurrent Submit() call
  139|     10|            m_interrupt = true;
  140|     10|            threads_to_join.swap(m_workers);
  141|     10|        }
  142|      0|        m_cv.notify_all();
  143|       |        // Help draining queue
  144|     10|        while (ProcessTask()) {}
  ------------------
  |  Branch (144:16): [True: 0, False: 10]
  ------------------
  145|       |        // Free resources
  146|     10|        for (auto& worker : threads_to_join) worker.join();
  ------------------
  |  Branch (146:27): [True: 0, False: 10]
  ------------------
  147|       |
  148|       |        // Since we currently wait for tasks completion, sanity-check empty queue
  149|     10|        LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  150|     10|        Assume(m_work_queue.empty());
  ------------------
  |  |  128|     10|#define Assume(val) inline_assertion_check<false>(val, std::source_location::current(), #val)
  ------------------
  151|       |        // Re-allow Start() now that all workers have exited
  152|     10|        m_interrupt = false;
  153|     10|    }
_ZN10ThreadPool11ProcessTaskEv:
  244|     10|    {
  245|     10|        std::packaged_task<void()> task;
  246|     10|        {
  247|     10|            LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  248|     10|            if (m_work_queue.empty()) return false;
  ------------------
  |  Branch (248:17): [True: 10, False: 0]
  ------------------
  249|       |
  250|       |            // Pop the task
  251|      0|            task = std::move(m_work_queue.front());
  252|      0|            m_work_queue.pop();
  253|      0|        }
  254|      0|        task();
  255|      0|        return true;
  256|     10|    }

_Z11SetMockTimeNSt3__16chrono8durationIxNS_5ratioILl1ELl1EEEEE:
   54|    732|{
   55|    732|    Assert(mock_time_in >= 0s);
  ------------------
  |  |  116|    732|#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
  ------------------
   56|    732|    g_mock_time.store(mock_time_in, std::memory_order_relaxed);
   57|    732|}
_ZN19MockableSteadyClock13ClearMockTimeEv:
   84|    732|{
   85|    732|    g_mock_steady_time.store(0ms, std::memory_order_relaxed);
   86|    732|}

_ZN19WalletInitInterfaceD2Ev:
   25|      2|    virtual ~WalletInitInterface() = default;

