_ZNK6google4hoth8internal17PayloadUpdateImpl8initiateEv:
   56|  2.38k|{
   57|  2.38k|    sendCommand(PAYLOAD_UPDATE_INITIATE);
  ------------------
  |  |  180|  2.38k|#define PAYLOAD_UPDATE_INITIATE 0
  ------------------
   58|  2.38k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl5eraseEjj:
   61|    734|{
   62|    734|    sendCommand(PAYLOAD_UPDATE_ERASE, offset, size);
  ------------------
  |  |  188|    734|#define PAYLOAD_UPDATE_ERASE 8
  ------------------
   63|    734|}
_ZNK6google4hoth8internal17PayloadUpdateImpl14findDescriptorERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPj:
   67|  2.92k|{
   68|  2.92k|    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);
   69|       |
   70|  2.92k|    if (*fd < 0)
  ------------------
  |  Branch (70:9): [True: 0, False: 2.92k]
  ------------------
   71|      0|    {
   72|      0|        (void)fd.release();
   73|      0|        throw errnoException(std::format("Failed to open file {}", path));
   74|      0|    }
   75|       |
   76|  2.92k|    auto seekRet = sys->lseek(*fd, 0, SEEK_END);
   77|  2.92k|    size_t fsize = seekRet;
   78|       |
   79|  2.92k|    if (seekRet < 0)
  ------------------
  |  Branch (79:9): [True: 0, False: 2.92k]
  ------------------
   80|      0|    {
   81|      0|        throw errnoException(std::format("Error seeking on file", path));
   82|      0|    }
   83|       |
   84|  2.92k|    uint64_t read_data = 0;
   85|  2.92k|    bool desc_found = false;
   86|       |
   87|       |    // Find the nearest aligned address to the end of the file. We can't
   88|       |    // assume that the file-size is aligned.
   89|  2.92k|    ssize_t offset = static_cast<ssize_t>(
   90|  2.92k|        (fsize / kImageDescriptorAlignment) * kImageDescriptorAlignment);
   91|  2.92k|    if (offset + sizeof(kDescriptorMagic) > fsize)
  ------------------
  |  Branch (91:9): [True: 461, False: 2.46k]
  ------------------
   92|    461|    {
   93|    461|        offset -= kImageDescriptorAlignment;
   94|    461|    }
   95|       |
   96|  4.09k|    for (; offset >= 0; offset -= kImageDescriptorAlignment)
  ------------------
  |  Branch (96:12): [True: 3.17k, False: 912]
  ------------------
   97|  3.17k|    {
   98|  3.17k|        auto seek = sys->lseek(*fd, offset, SEEK_SET);
   99|  3.17k|        if (seek < 0)
  ------------------
  |  Branch (99:13): [True: 0, False: 3.17k]
  ------------------
  100|      0|        {
  101|      0|            throw errnoException(std::format("Error seeking on file", path));
  102|      0|        }
  103|       |
  104|  3.17k|        auto actualReadSize = sys->read(*fd, &read_data, sizeof(read_data));
  105|       |
  106|  3.17k|        if (actualReadSize < 0)
  ------------------
  |  Branch (106:13): [True: 0, False: 3.17k]
  ------------------
  107|      0|        {
  108|      0|            throw errnoException(
  109|      0|                std::format("Failed to read from file {}", path));
  110|      0|        }
  111|       |
  112|  3.17k|        if (read_data == kDescriptorMagic)
  ------------------
  |  Branch (112:13): [True: 2.01k, False: 1.16k]
  ------------------
  113|  2.01k|        {
  114|  2.01k|            if (desc_offset)
  ------------------
  |  Branch (114:17): [True: 2.01k, False: 0]
  ------------------
  115|  2.01k|            {
  116|  2.01k|                *desc_offset = offset;
  117|  2.01k|                desc_found = true;
  118|  2.01k|                break;
  119|  2.01k|            }
  120|  2.01k|        }
  121|  3.17k|    }
  122|       |
  123|  2.92k|    return desc_found;
  124|  2.92k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl27eraseAndSendStaticWPRegionsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEj:
  128|  2.01k|{
  129|  2.01k|    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);
  130|       |
  131|  2.01k|    if (*fd < 0)
  ------------------
  |  Branch (131:9): [True: 0, False: 2.01k]
  ------------------
  132|      0|    {
  133|      0|        (void)fd.release();
  134|      0|        throw errnoException(std::format("Failed to open file {}", path));
  135|      0|    }
  136|       |
  137|  2.01k|    struct image_descriptor descriptor;
  138|       |
  139|  2.01k|    if (sys->lseek(*fd, desc_offset, SEEK_SET) < 0)
  ------------------
  |  Branch (139:9): [True: 0, False: 2.01k]
  ------------------
  140|      0|    {
  141|      0|        throw errnoException(std::format("Error seeking on file", path));
  142|      0|    }
  143|  2.01k|    auto actualReadSize = sys->read(*fd, &descriptor, sizeof(descriptor));
  144|       |
  145|  2.01k|    if (actualReadSize < 0)
  ------------------
  |  Branch (145:9): [True: 0, False: 2.01k]
  ------------------
  146|      0|    {
  147|      0|        throw errnoException(std::format("Failed to read from file {}", path));
  148|      0|    }
  149|       |
  150|  2.01k|    if (descriptor.descriptor_magic != DESCRIPTOR_MAGIC ||
  ------------------
  |  |   70|  4.02k|#define DESCRIPTOR_MAGIC 0x5f435344474d495f // "_IMGDSC_"
  ------------------
  |  Branch (150:9): [True: 0, False: 2.01k]
  ------------------
  151|  2.01k|        descriptor.descriptor_offset != desc_offset ||
  ------------------
  |  Branch (151:9): [True: 142, False: 1.86k]
  ------------------
  152|  1.86k|        descriptor.region_count == 0)
  ------------------
  |  Branch (152:9): [True: 124, False: 1.74k]
  ------------------
  153|    266|    {
  154|    266|        throw errnoException(
  155|    266|            std::format("Invalid descriptor at offset {}", path));
  156|    266|    }
  157|       |
  158|  1.74k|    std::vector<struct image_region> image_regions(descriptor.region_count);
  159|       |
  160|  1.74k|    actualReadSize =
  161|  1.74k|        sys->read(*fd, image_regions.data(),
  162|  1.74k|                  sizeof(struct image_region) * descriptor.region_count);
  163|  1.74k|    if (actualReadSize < 0)
  ------------------
  |  Branch (163:9): [True: 0, False: 1.74k]
  ------------------
  164|      0|    {
  165|      0|        throw errnoException(std::format("Failed to read from file {}", path));
  166|      0|    }
  167|       |
  168|       |    // Erase all the static and Write Protected regions of the payload
  169|   134k|    for (uint32_t i = 0; i < descriptor.region_count; i++)
  ------------------
  |  Branch (169:26): [True: 132k, False: 1.24k]
  ------------------
  170|   132k|    {
  171|   132k|        if ((image_regions[i].region_attributes & IMAGE_REGION_STATIC) ||
  ------------------
  |  |   55|   132k|#define IMAGE_REGION_STATIC                     (1 << 0)
  ------------------
  |  Branch (171:13): [True: 2.15k, False: 130k]
  ------------------
  172|   130k|            (image_regions[i].region_attributes & IMAGE_REGION_WRITE_PROTECTED))
  ------------------
  |  |   57|   130k|#define IMAGE_REGION_WRITE_PROTECTED            (1 << 2)
  ------------------
  |  Branch (172:13): [True: 944, False: 129k]
  ------------------
  173|  3.10k|        {
  174|  3.10k|            if (image_regions[i].region_size == 0 ||
  ------------------
  |  Branch (174:17): [True: 45, False: 3.05k]
  ------------------
  175|  3.05k|                (image_regions[i].region_size % kSectorSizeBytes) != 0)
  ------------------
  |  Branch (175:17): [True: 456, False: 2.59k]
  ------------------
  176|    501|            {
  177|    501|                throw errnoException(std::format("invalid staging area size"));
  178|    501|            }
  179|  2.59k|            uint32_t regionOffset = image_regions[i].region_offset;
  180|  2.59k|            uint32_t toEraseSize = image_regions[i].region_size;
  181|  25.3M|            while (toEraseSize >= kEraseChunkSizeBytes)
  ------------------
  |  Branch (181:20): [True: 25.3M, False: 2.59k]
  ------------------
  182|  25.3M|            {
  183|  25.3M|                sendCommand(PAYLOAD_UPDATE_ERASE, regionOffset,
  ------------------
  |  |  188|  25.3M|#define PAYLOAD_UPDATE_ERASE 8
  ------------------
  184|  25.3M|                            kEraseChunkSizeBytes);
  185|  25.3M|                regionOffset += kEraseChunkSizeBytes;
  186|  25.3M|                toEraseSize -= kEraseChunkSizeBytes;
  187|  25.3M|            }
  188|  2.59k|            if (toEraseSize > 0)
  ------------------
  |  Branch (188:17): [True: 1.84k, False: 751]
  ------------------
  189|  1.84k|            {
  190|  1.84k|                sendCommand(PAYLOAD_UPDATE_ERASE, regionOffset, toEraseSize);
  ------------------
  |  |  188|  1.84k|#define PAYLOAD_UPDATE_ERASE 8
  ------------------
  191|  1.84k|            }
  192|  2.59k|        }
  193|   132k|    }
  194|       |
  195|       |    // Read and send static and WP sections of the payload
  196|  28.0k|    for (uint32_t i = 0; i < descriptor.region_count; i++)
  ------------------
  |  Branch (196:26): [True: 27.8k, False: 286]
  ------------------
  197|  27.8k|    {
  198|  27.8k|        if ((image_regions[i].region_attributes & IMAGE_REGION_STATIC) ||
  ------------------
  |  |   55|  27.8k|#define IMAGE_REGION_STATIC                     (1 << 0)
  ------------------
  |  Branch (198:13): [True: 1.31k, False: 26.4k]
  ------------------
  199|  26.4k|            (image_regions[i].region_attributes & IMAGE_REGION_WRITE_PROTECTED))
  ------------------
  |  |   57|  26.4k|#define IMAGE_REGION_WRITE_PROTECTED            (1 << 2)
  ------------------
  |  Branch (199:13): [True: 436, False: 26.0k]
  ------------------
  200|  1.75k|        {
  201|  1.75k|            uint32_t offset = image_regions[i].region_offset;
  202|  1.75k|            auto regionSize = image_regions[i].region_size;
  203|  1.75k|            size_t readSize = 0;
  204|  1.75k|            std::vector<uint8_t> readBuffer(max_packet_size);
  205|       |
  206|  1.75k|            if (sys->lseek(*fd, offset, SEEK_SET) != offset)
  ------------------
  |  Branch (206:17): [True: 536, False: 1.21k]
  ------------------
  207|    536|            {
  208|    536|                throw errnoException(
  209|    536|                    std::format("Failed to read file size {}", path));
  210|    536|            }
  211|  1.21k|            do
  212|  11.2k|            {
  213|  11.2k|                if (regionSize <= max_packet_size)
  ------------------
  |  Branch (213:21): [True: 869, False: 10.3k]
  ------------------
  214|    869|                {
  215|    869|                    readSize = regionSize;
  216|    869|                }
  217|  10.3k|                else
  218|  10.3k|                {
  219|  10.3k|                    readSize = max_packet_size;
  220|  10.3k|                }
  221|       |
  222|  11.2k|                if (!sys->read(*fd, readBuffer.data(), readSize))
  ------------------
  |  Branch (222:21): [True: 422, False: 10.8k]
  ------------------
  223|    422|                {
  224|    422|                    throw errnoException(
  225|    422|                        std::format("Failed to read from file {}", path));
  226|    422|                }
  227|       |
  228|       |                // Decided not to use initializer list to create the span here
  229|       |                // as actualReadSize is ssize_t and we'd need to static_cast
  230|  10.8k|                trimAndSend(std::span<uint8_t>(readBuffer.data(), readSize),
  231|  10.8k|                            offset);
  232|  10.8k|                offset += readSize;
  233|  10.8k|                regionSize -= readSize;
  234|       |
  235|  10.8k|            } while (regionSize); // actualReadSize will be 0 when EOF is
  ------------------
  |  Branch (235:22): [True: 10.0k, False: 797]
  ------------------
  236|       |                                  // reached, exit loop
  237|  1.21k|        }
  238|  27.8k|    }
  239|  1.24k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl20eraseAndSendStaticWPERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  242|  2.92k|{
  243|  2.92k|    uint32_t desc_offset = 0;
  244|       |
  245|  2.92k|    if (!findDescriptor(path, &desc_offset))
  ------------------
  |  Branch (245:9): [True: 912, False: 2.01k]
  ------------------
  246|    912|    {
  247|    912|        throw errnoException(std::format("No valid descriptor found"));
  248|    912|    }
  249|       |
  250|  2.01k|    eraseAndSendStaticWPRegions(path, desc_offset);
  251|  2.01k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl4readEjNSt3__14spanIhLm18446744073709551615EEE:
  254|  1.80k|{
  255|  1.80k|    std::vector<uint8_t> buf;
  256|  1.80k|    auto rsp = sendCommand(buf, PAYLOAD_UPDATE_READ, offset, data.size());
  ------------------
  |  |  186|  1.80k|#define PAYLOAD_UPDATE_READ 6
  ------------------
  257|  1.80k|    if (rsp.size() != data.size())
  ------------------
  |  Branch (257:9): [True: 1.52k, False: 287]
  ------------------
  258|  1.52k|    {
  259|  1.52k|        stdplus::print(
  260|  1.52k|            stderr,
  261|  1.52k|            "Payload command received a short response from Hoth `{} < {}`\n",
  262|  1.52k|            rsp.size(), data.size());
  263|  1.52k|        throw ResponseFailure();
  264|  1.52k|    }
  265|    287|    memcpy(data.data(), rsp.data(), data.size());
  266|    287|}
_ZNK6google4hoth8internal17PayloadUpdateImpl6verifyEv:
  269|    444|{
  270|    444|    payload_update_packet request = {};
  271|    444|    request.type = PAYLOAD_UPDATE_VERIFY_DESCRIPTOR;
  ------------------
  |  |  191|    444|#define PAYLOAD_UPDATE_VERIFY_DESCRIPTOR 11
  ------------------
  272|    444|    auto buf = hostCmd->sendCommand(
  273|    444|        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |   58|    444|#define EC_CMD_BOARD_SPECIFIC_BASE 0x3E00
  ------------------
                      EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |  146|    444|#define EC_PRV_CMD_HOTH_PAYLOAD_UPDATE 0x0005
  ------------------
  274|    444|        &request, sizeof(request));
  275|    444|    std::span<uint8_t> rsp = buf;
  276|    444|    auto& hdr = stdplus::raw::extractRef<RspHeader>(rsp);
  277|       |
  278|       |    // In case PAYLOAD_UPDATE_VERIFY is not supported (EC_RES_ERROR),
  279|       |    // we fall back to PAYLOAD_UPDATE_VERIFY instead.
  280|    444|    if (hdr.result == EC_RES_INVALID_PARAM || hdr.result == EC_RES_ERROR)
  ------------------
  |  Branch (280:9): [True: 0, False: 444]
  |  Branch (280:47): [True: 0, False: 444]
  ------------------
  281|      0|    {
  282|      0|        sendCommand(PAYLOAD_UPDATE_VERIFY);
  ------------------
  |  |  184|      0|#define PAYLOAD_UPDATE_VERIFY 4
  ------------------
  283|      0|        return;
  284|      0|    }
  285|    444|    if (hdr.result != EC_RES_SUCCESS)
  ------------------
  |  Branch (285:9): [True: 0, False: 444]
  ------------------
  286|      0|    {
  287|       |        stdplus::print(stderr, "VERIFY_DESCRIPTOR error: {:#x}\n",
  288|      0|                       static_cast<uint16_t>(hdr.result));
  289|      0|        throw ResponseFailure();
  290|      0|    }
  291|    444|}
_ZNK6google4hoth8internal17PayloadUpdateImpl9getStatusEv:
  294|    572|{
  295|    572|    std::vector<uint8_t> buf;
  296|    572|    std::span<const uint8_t> output =
  297|    572|        sendCommand(buf, PAYLOAD_UPDATE_GET_STATUS);
  ------------------
  |  |  187|    572|#define PAYLOAD_UPDATE_GET_STATUS 7
  ------------------
  298|       |
  299|    572|    return stdplus::raw::copyFrom<payload_update_status>(output);
  300|    572|}
_ZNK6google4hoth8internal17PayloadUpdateImpl8activateENS1_4SideENS1_11PersistenceE:
  303|    540|{
  304|    540|    ActivateRequest request;
  305|    540|    request.header.offset = 0;
  306|    540|    request.header.len = sizeof(request.activate);
  307|    540|    request.header.type = PAYLOAD_UPDATE_ACTIVATE;
  ------------------
  |  |  185|    540|#define PAYLOAD_UPDATE_ACTIVATE 5
  ------------------
  308|    540|    request.activate.half = static_cast<uint8_t>(side);
  309|    540|    request.activate.make_persistent = static_cast<uint8_t>(persistence);
  310|       |
  311|    540|    sendCommand(
  312|    540|        {reinterpret_cast<const uint8_t*>(&request), sizeof(ActivateRequest)});
  313|    540|}
_ZNK6google4hoth8internal17PayloadUpdateImpl7confirmE29payload_update_confirm_optionjm:
  318|    687|{
  319|    687|    ConfirmRequest request;
  320|    687|    request.header.offset = 0;
  321|    687|    request.header.len = sizeof(request.confirm);
  322|    687|    request.header.type = PAYLOAD_UPDATE_CONFIRM;
  ------------------
  |  |  190|    687|#define PAYLOAD_UPDATE_CONFIRM 10
  ------------------
  323|    687|    request.confirm.option = option;
  324|    687|    request.confirm.timeout_value = boost::endian::native_to_little(timeout);
  325|    687|    request.confirm.confirmation_cookie =
  326|    687|        boost::endian::native_to_little(confirmation_cookie);
  327|       |
  328|    687|    std::vector<uint8_t> buf = hostCmd->sendCommand(
  329|    687|        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |   58|    687|#define EC_CMD_BOARD_SPECIFIC_BASE 0x3E00
  ------------------
                      EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |  146|    687|#define EC_PRV_CMD_HOTH_PAYLOAD_UPDATE 0x0005
  ------------------
  330|    687|        &request, sizeof(request));
  331|       |    // Extract the response header out when returning the span
  332|    687|    std::span<const uint8_t> output = buf;
  333|    687|    auto rsp = stdplus::raw::extract<RspHeader>(output);
  334|    687|    if (rsp.result == HOTH_PAYLOAD_UPDATE_CONFIRM_NO_PENDING_PAYLOAD)
  ------------------
  |  Branch (334:9): [True: 0, False: 687]
  ------------------
  335|      0|    {
  336|      0|        return std::nullopt;
  337|      0|    }
  338|       |
  339|    687|    if (rsp.result != EC_RES_SUCCESS)
  ------------------
  |  Branch (339:9): [True: 0, False: 687]
  ------------------
  340|      0|    {
  341|      0|        stdplus::print(
  342|      0|            stderr,
  343|      0|            "Payload confirm command received a bad response from Hoth {:#x}\n",
  344|      0|            static_cast<uint16_t>(rsp.result));
  345|      0|        throw ResponseFailure();
  346|      0|    }
  347|       |
  348|    687|    return stdplus::raw::copyFrom<payload_update_confirm_response>(output);
  349|    687|}
_ZNK6google4hoth8internal17PayloadUpdateImpl4sendERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  382|    900|{
  383|    900|    Fd fd(sys->open(path.c_str(), O_RDONLY), sys);
  384|       |
  385|    900|    if (*fd < 0)
  ------------------
  |  Branch (385:9): [True: 0, False: 900]
  ------------------
  386|      0|    {
  387|      0|        (void)fd.release();
  388|      0|        throw errnoException(std::format("Failed to open file {}", path));
  389|      0|    }
  390|       |
  391|    900|    std::array<uint8_t, max_packet_size> readBuffer;
  392|    900|    uint32_t offset = 0;
  393|    900|    ssize_t actualReadSize = 0;
  394|       |    // Read and send payload until we reach EOF of the given file
  395|    900|    do
  396|  7.72k|    {
  397|  7.72k|        actualReadSize = sys->read(*fd, readBuffer.data(), max_packet_size);
  398|       |
  399|  7.72k|        if (actualReadSize < 0)
  ------------------
  |  Branch (399:13): [True: 0, False: 7.72k]
  ------------------
  400|      0|        {
  401|      0|            throw errnoException(
  402|      0|                std::format("Failed to read from file {}", path));
  403|      0|        }
  404|  7.72k|        if (actualReadSize > 0)
  ------------------
  |  Branch (404:13): [True: 6.82k, False: 900]
  ------------------
  405|  6.82k|        {
  406|       |            // Decided not to use initializer list to create the span here as
  407|       |            // actualReadSize is ssize_t and we'd need to static_cast
  408|  6.82k|            trimAndSend(std::span<uint8_t>(readBuffer.data(), actualReadSize),
  409|  6.82k|                        offset);
  410|  6.82k|            offset += actualReadSize;
  411|  6.82k|        }
  412|       |        // actualReadSize will be 0 when EOF is reached, exit loop
  413|  7.72k|    } while (actualReadSize);
  ------------------
  |  Branch (413:14): [True: 6.82k, False: 900]
  ------------------
  414|    900|}
_ZNK6google4hoth8internal17PayloadUpdateImpl11trimAndSendENSt3__14spanIKhLm18446744073709551615EEEj:
  425|  17.6k|{
  426|       |    // Allocate the payload buffer at "buffer".
  427|       |    // "request" will point to the payload_update_packet section of the buffer
  428|       |    // "request_payload" will point to the beginning of the payload
  429|       |    // (after the payload_update_packet header).
  430|  17.6k|    std::array<uint8_t, sizeof(payload_update_packet) + max_packet_size> buffer;
  431|  17.6k|    payload_update_packet* request =
  432|  17.6k|        reinterpret_cast<payload_update_packet*>(buffer.data());
  433|  17.6k|    uint8_t* request_payload = &buffer[sizeof(payload_update_packet)];
  434|       |
  435|  17.6k|    const size_t dataSize = data.size();
  436|  17.6k|    if (dataSize > max_packet_size)
  ------------------
  |  Branch (436:9): [True: 0, False: 17.6k]
  ------------------
  437|      0|    {
  438|      0|        throw errnoException(
  439|      0|            "data to send cannot be bigger than max_packet_size");
  440|      0|    }
  441|  17.6k|    size_t localOffset = SizeToSkip(data);
  442|  17.6k|    if (localOffset >= dataSize)
  ------------------
  |  Branch (442:9): [True: 532, False: 17.0k]
  ------------------
  443|    532|    {
  444|       |        // No need to send any payload
  445|    532|        return;
  446|    532|    }
  447|  17.0k|    size_t max_size_to_send = std::min(dataSize - localOffset, max_packet_size);
  448|  17.0k|    size_t size_to_send =
  449|  17.0k|        SizeToSend(data.subspan(localOffset, max_size_to_send));
  450|       |
  451|       |    // Construct and send payload
  452|  17.0k|    request->offset = globalOffset + localOffset;
  453|  17.0k|    request->len = size_to_send;
  454|  17.0k|    request->type = PAYLOAD_UPDATE_CONTINUE;
  ------------------
  |  |  181|  17.0k|#define PAYLOAD_UPDATE_CONTINUE 1
  ------------------
  455|  17.0k|    memcpy(request_payload, &data[localOffset], size_to_send);
  456|  17.0k|    sendCommand({buffer.data(), sizeof(*request) + size_to_send});
  457|  17.0k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl11sendCommandEhjj:
  461|  25.3M|{
  462|  25.3M|    std::vector<uint8_t> buf;
  463|  25.3M|    (void)sendCommand(buf, command, offset, len);
  464|  25.3M|}
_ZNK6google4hoth8internal17PayloadUpdateImpl11sendCommandENSt3__14spanIKhLm18446744073709551615EEE:
  467|  17.6k|{
  468|  17.6k|    std::vector<uint8_t> buf;
  469|  17.6k|    (void)sendCommand(buf, request);
  470|  17.6k|}
_ZNK6google4hoth8internal17PayloadUpdateImpl11sendCommandERNSt3__16vectorIhNS3_9allocatorIhEEEEhjj:
  475|  25.3M|{
  476|       |    // For most basic commands, request offset and length are zero
  477|  25.3M|    payload_update_packet request;
  478|  25.3M|    request.offset = offset;
  479|  25.3M|    request.len = len;
  480|  25.3M|    request.type = command;
  481|  25.3M|    return sendCommand(buf, {reinterpret_cast<const uint8_t*>(&request),
  482|  25.3M|                             sizeof(payload_update_packet)});
  483|  25.3M|}
_ZNK6google4hoth8internal17PayloadUpdateImpl11sendCommandERNSt3__16vectorIhNS3_9allocatorIhEEEENS3_4spanIKhLm18446744073709551615EEE:
  487|  25.3M|{
  488|  25.3M|    buf = hostCmd->sendCommand(
  489|  25.3M|        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |   58|  25.3M|#define EC_CMD_BOARD_SPECIFIC_BASE 0x3E00
  ------------------
                      EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_UPDATE, 0,
  ------------------
  |  |  146|  25.3M|#define EC_PRV_CMD_HOTH_PAYLOAD_UPDATE 0x0005
  ------------------
  490|  25.3M|        request.data(), request.size());
  491|       |    // Extract the response header out when returning the span
  492|  25.3M|    std::span<const uint8_t> output = buf;
  493|  25.3M|    auto rsp = stdplus::raw::extract<RspHeader>(output);
  494|  25.3M|    if (rsp.result != EC_RES_SUCCESS)
  ------------------
  |  Branch (494:9): [True: 0, False: 25.3M]
  ------------------
  495|      0|    {
  496|      0|        stdplus::print(
  497|      0|            stderr, "Payload command received a bad response from Hoth {:#x}\n",
  498|      0|            static_cast<uint16_t>(rsp.result));
  499|      0|        throw ResponseFailure();
  500|      0|    }
  501|       |
  502|  25.3M|    return output;
  503|  25.3M|}
payload_update.cpp:_ZN6google4hoth8internal12_GLOBAL__N_110SizeToSkipENSt3__14spanIKhLm18446744073709551615EEE:
  355|  17.6k|{
  356|  17.6k|    size_t i;
  357|   285k|    for (i = 0; i < data.size(); i++)
  ------------------
  |  Branch (357:17): [True: 285k, False: 532]
  ------------------
  358|   285k|    {
  359|   285k|        if (data[i] != 0xff)
  ------------------
  |  Branch (359:13): [True: 17.0k, False: 268k]
  ------------------
  360|  17.0k|        {
  361|  17.0k|            break;
  362|  17.0k|        }
  363|   285k|    }
  364|  17.6k|    return i;
  365|  17.6k|}
payload_update.cpp:_ZN6google4hoth8internal12_GLOBAL__N_110SizeToSendENSt3__14spanIKhLm18446744073709551615EEE:
  368|  17.0k|{
  369|  17.0k|    size_t i;
  370|   110k|    for (i = data.size(); i > 0; i--)
  ------------------
  |  Branch (370:27): [True: 110k, False: 0]
  ------------------
  371|   110k|    {
  372|   110k|        if (data[i - 1] != 0xff)
  ------------------
  |  Branch (372:13): [True: 17.0k, False: 93.6k]
  ------------------
  373|  17.0k|        {
  374|  17.0k|            break;
  375|  17.0k|        }
  376|   110k|    }
  377|  17.0k|    return i;
  378|  17.0k|}

_ZN6google4hoth8internal17PayloadUpdateImpl7closeFdEOiRPKNS1_3SysE:
  107|  5.83k|    {
  108|  5.83k|        if (sys)
  ------------------
  |  Branch (108:13): [True: 5.83k, False: 0]
  ------------------
  109|  5.83k|        {
  110|  5.83k|            sys->close(fd);
  111|  5.83k|        }
  112|  5.83k|    }
_ZN6google4hoth8internal17PayloadUpdateImplC2EPNS1_11HostCommandEPKNS1_3SysE:
   73|  1.03k|        hostCmd(hostCmd), sys(sys)
   74|  1.03k|    {}

_ZN6google4hoth8internal14errnoExceptionERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   49|  2.63k|{
   50|       |    return std::system_error(errno, std::generic_category(), message);
   51|  2.63k|}

LLVMFuzzerTestOneInput:
  117|  1.03k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  118|  1.03k|    if (size < 2) return 0;
  ------------------
  |  Branch (118:9): [True: 1, False: 1.03k]
  ------------------
  119|       |
  120|  1.03k|    FuzzedDataProvider provider(data, size);
  121|       |
  122|       |    // Allocate up to 80% of fuzzer data to represent the firmware file contents
  123|  1.03k|    size_t file_data_len = provider.ConsumeIntegralInRange<size_t>(0, provider.remaining_bytes() * 8 / 10);
  124|  1.03k|    std::vector<uint8_t> file_data = provider.ConsumeBytes<uint8_t>(file_data_len);
  125|       |
  126|  1.03k|    FuzzerSys fuzzer_sys(file_data.data(), file_data.size());
  127|  1.03k|    FuzzerHostCommand fuzzer_host_cmd;
  128|  1.03k|    google::hoth::internal::PayloadUpdateImpl payload_update(&fuzzer_host_cmd, &fuzzer_sys);
  129|       |
  130|  1.03k|    size_t action_count = 0;
  131|  12.0k|    while (provider.remaining_bytes() > 0 && action_count < 20) {
  ------------------
  |  Branch (131:12): [True: 11.3k, False: 704]
  |  Branch (131:46): [True: 10.9k, False: 330]
  ------------------
  132|  10.9k|        action_count++;
  133|  10.9k|        uint8_t action = provider.ConsumeIntegralInRange<uint8_t>(0, 8);
  134|  10.9k|        try {
  135|  10.9k|            switch (action) {
  ------------------
  |  Branch (135:21): [True: 10.9k, False: 0]
  ------------------
  136|  2.38k|                case 0: {
  ------------------
  |  Branch (136:17): [True: 2.38k, False: 8.60k]
  ------------------
  137|  2.38k|                    payload_update.initiate();
  138|  2.38k|                    break;
  139|      0|                }
  140|    734|                case 1: {
  ------------------
  |  Branch (140:17): [True: 734, False: 10.2k]
  ------------------
  141|    734|                    uint32_t offset = provider.ConsumeIntegral<uint32_t>();
  142|    734|                    uint32_t size = provider.ConsumeIntegral<uint32_t>();
  143|    734|                    payload_update.erase(offset, size);
  144|    734|                    break;
  145|      0|                }
  146|  2.92k|                case 2: {
  ------------------
  |  Branch (146:17): [True: 2.92k, False: 8.07k]
  ------------------
  147|  2.92k|                    payload_update.eraseAndSendStaticWP("/tmp/fuzz_file");
  148|  2.92k|                    break;
  149|      0|                }
  150|  1.80k|                case 3: {
  ------------------
  |  Branch (150:17): [True: 1.80k, False: 9.18k]
  ------------------
  151|  1.80k|                    uint32_t offset = provider.ConsumeIntegral<uint32_t>();
  152|  1.80k|                    uint32_t read_len = provider.ConsumeIntegralInRange<uint32_t>(0, 1024);
  153|  1.80k|                    std::vector<uint8_t> read_buf(read_len);
  154|  1.80k|                    payload_update.read(offset, read_buf);
  155|  1.80k|                    break;
  156|      0|                }
  157|    444|                case 4: {
  ------------------
  |  Branch (157:17): [True: 444, False: 10.5k]
  ------------------
  158|    444|                    payload_update.verify();
  159|    444|                    break;
  160|      0|                }
  161|    572|                case 5: {
  ------------------
  |  Branch (161:17): [True: 572, False: 10.4k]
  ------------------
  162|    572|                    payload_update.getStatus();
  163|    572|                    break;
  164|      0|                }
  165|    540|                case 6: {
  ------------------
  |  Branch (165:17): [True: 540, False: 10.4k]
  ------------------
  166|    540|                    auto side = provider.PickValueInArray({google::hoth::internal::Side::A, google::hoth::internal::Side::B});
  167|    540|                    auto persistence = provider.PickValueInArray({google::hoth::internal::Persistence::kNonPersistent, google::hoth::internal::Persistence::kPersistent});
  168|    540|                    payload_update.activate(side, persistence);
  169|    540|                    break;
  170|      0|                }
  171|    900|                case 7: {
  ------------------
  |  Branch (171:17): [True: 900, False: 10.0k]
  ------------------
  172|    900|                    payload_update.send("/tmp/fuzz_file");
  173|    900|                    break;
  174|      0|                }
  175|    687|                case 8: {
  ------------------
  |  Branch (175:17): [True: 687, False: 10.3k]
  ------------------
  176|    687|                    auto option = provider.PickValueInArray({
  177|    687|                        payload_update_confirm_option::Enable,
  178|    687|                        payload_update_confirm_option::Enable_with_timeout,
  179|    687|                        payload_update_confirm_option::Disable,
  180|    687|                        payload_update_confirm_option::Confirm,
  181|    687|                        payload_update_confirm_option::Get_timeout_values
  182|    687|                    });
  183|    687|                    uint32_t timeout = provider.ConsumeIntegral<uint32_t>();
  184|    687|                    uint64_t cookie = provider.ConsumeIntegral<uint64_t>();
  185|    687|                    payload_update.confirm(option, timeout, cookie);
  186|    687|                    break;
  187|      0|                }
  188|  10.9k|            }
  189|  10.9k|        } catch (...) {
  190|       |            // Catch expected exceptions (e.g. from mock filesystem or D-Bus response failures)
  191|  5.41k|        }
  192|  10.9k|    }
  193|       |
  194|  1.03k|    return 0;
  195|  1.03k|}
_ZN9FuzzerSysC2EPKhm:
   37|  1.03k|    FuzzerSys(const uint8_t* data, size_t size) : data_(data), size_(size), offset_(0) {}
_ZNK9FuzzerSys4openEPKci:
   39|  5.83k|    int open(const char* pathname, int flags) const override {
   40|  5.83k|        return 42; // dummy fd
   41|  5.83k|    }
_ZNK9FuzzerSys5closeEi:
   43|  5.83k|    int close(int fd) const override {
   44|  5.83k|        return 0;
   45|  5.83k|    }
_ZNK9FuzzerSys5lseekEili:
   47|  9.86k|    off_t lseek(int fd, off_t offset, int whence) const override {
   48|  9.86k|        if (whence == SEEK_SET) {
  ------------------
  |  Branch (48:13): [True: 6.94k, False: 2.92k]
  ------------------
   49|  6.94k|            if (offset < 0 || static_cast<size_t>(offset) > size_) return -1;
  ------------------
  |  Branch (49:17): [True: 0, False: 6.94k]
  |  Branch (49:31): [True: 536, False: 6.40k]
  ------------------
   50|  6.40k|            offset_ = offset;
   51|  6.40k|        } else if (whence == SEEK_END) {
  ------------------
  |  Branch (51:20): [True: 2.92k, False: 0]
  ------------------
   52|  2.92k|            offset_ = size_;
   53|  2.92k|        } else if (whence == SEEK_CUR) {
  ------------------
  |  Branch (53:20): [True: 0, False: 0]
  ------------------
   54|      0|            if (static_cast<ssize_t>(offset_) + offset < 0 || static_cast<size_t>(offset_ + offset) > size_) return -1;
  ------------------
  |  Branch (54:17): [True: 0, False: 0]
  |  Branch (54:63): [True: 0, False: 0]
  ------------------
   55|      0|            offset_ += offset;
   56|      0|        }
   57|  9.33k|        return offset_;
   58|  9.86k|    }
_ZNK9FuzzerSys4readEiPvm:
   60|  25.8k|    ssize_t read(int fd, void* buf, size_t count) const override {
   61|  25.8k|        if (offset_ >= size_) return 0;
  ------------------
  |  Branch (61:13): [True: 1.44k, False: 24.4k]
  ------------------
   62|  24.4k|        size_t to_read = std::min(count, size_ - offset_);
   63|  24.4k|        std::memcpy(buf, data_ + offset_, to_read);
   64|  24.4k|        offset_ += to_read;
   65|  24.4k|        return to_read;
   66|  25.8k|    }
_ZN17FuzzerHostCommand11sendCommandEthPKvm:
   91|  25.3M|    std::vector<uint8_t> sendCommand(uint16_t command, uint8_t commandVersion, const void* request, size_t requestSize) override {
   92|       |        // Return a dummy response with EC_RES_SUCCESS
   93|  25.3M|        std::vector<uint8_t> rsp(sizeof(google::hoth::internal::RspHeader), 0);
   94|  25.3M|        auto* hdr = reinterpret_cast<google::hoth::internal::RspHeader*>(rsp.data());
   95|  25.3M|        hdr->result = google::hoth::internal::EC_RES_SUCCESS;
   96|  25.3M|        return rsp;
   97|  25.3M|    }

_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEEC2IJRKS6_EEESB_DpOT_:
   60|  5.83k|            as(std::forward<Vs>(vs)...), maybeT(std::move(maybeV))
   61|  5.83k|        {}
_ZNKR7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEEdeEv:
  110|  41.5k|        {
  111|  41.5k|            return *maybeT;
  112|  41.5k|        }
_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEED2Ev:
   92|  5.83k|        {
   93|  5.83k|            reset();
   94|  5.83k|        }
_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEE5resetEv:
  176|  5.83k|        {
  177|  5.83k|            reset(std::nullopt);
  178|  5.83k|        }
_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEE5resetEONSt3__18optionalIiEE:
  160|  5.83k|        {
  161|  5.83k|            maybeDrop(std::index_sequence_for<As...>());
  162|  5.83k|            maybeT = std::move(maybeV);
  163|  5.83k|        }
_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7HandleFINS7_7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEEE9maybeDropIJLm0EEEEvNSt3__116integer_sequenceImJXspT_EEEE:
  228|  5.83k|        {
  229|  5.83k|            if (maybeT)
  ------------------
  |  Branch (229:17): [True: 5.83k, False: 0]
  ------------------
  230|  5.83k|            {
  231|  5.83k|                Drop()(std::move(*maybeT), std::get<Indices>(as)...);
  232|  5.83k|            }
  233|  5.83k|        }
_ZN7stdplus7ManagedIiJPKN6google4hoth8internal3SysEEE7DropperIXadL_ZNS3_17PayloadUpdateImpl7closeFdEOiRS6_EEEclESA_SB_:
  240|  5.83k|        {
  241|  5.83k|            drop(std::move(t), as...);
  242|  5.83k|        }

_ZN7stdplus5printIJmmEEEvP8_IO_FILENSt3__119basic_format_stringIcJDpNS3_13type_identityIT_E4typeEEEEDpOS6_:
   31|  1.52k|{
   32|  1.52k|    Printer<false>::print(stream, fmt, std::forward<Args>(args)...);
   33|  1.52k|}
_ZN7stdplus7PrinterILb0EE5printIJmmEEEvP8_IO_FILENSt3__119basic_format_stringIcJDpNS5_13type_identityIT_E4typeEEEEDpOS8_:
   17|  1.52k|    {
   18|  1.52k|        stdplus::StrBuf buf;
   19|  1.52k|        std::format_to(std::back_inserter(buf), fmt,
   20|  1.52k|                       std::forward<Args>(args)...);
   21|       |        if constexpr (ln)
   22|       |        {
   23|       |            buf.push_back('\n');
   24|       |        }
   25|  1.52k|        prints(stream, buf);
   26|  1.52k|    }

_ZN7stdplus3raw10extractRefIN6google4hoth8internal9RspHeaderENS0_9UnAlignedETkNS_17TriviallyCopyableEhS5_EERT2_RNSt3__14spanIT1_Lm18446744073709551615EEE:
  170|    444|{
  171|    444|    Tp& ret = refFrom<Tp, A>(data);
  172|    444|    static_assert(sizeof(Tp) % sizeof(IntT) == 0);
  173|    444|    data = data.subspan(sizeof(Tp) / sizeof(IntT));
  174|    444|    return ret; // NOLINT(clang-analyzer-cplusplus.InnerPointer)
  175|    444|}
_ZN7stdplus3raw7refFromITkNS_17TriviallyCopyableEN6google4hoth8internal9RspHeaderENS0_9UnAlignedETkNS0_6detail15ContainsTrivialERNSt3__14spanIhLm18446744073709551615EEES5_EERT2_OT1_:
  115|    444|    {                                                                          \
  116|    444|        static_assert(std::is_same_v<A, Aligned> ||                            \
  117|    444|                      sizeof(*std::data(c)) % alignof(Tp) == 0);               \
  118|    444|        const size_t bytes = std::size(c) * sizeof(*std::data(c));             \
  119|    444|        if (bytes comp sizeof(Tp))                                             \
  ------------------
  |  Branch (119:13): [True: 0, False: 444]
  ------------------
  120|    444|        {                                                                      \
  121|      0|            throw exception::Incomplete(                                       \
  122|      0|                std::format(#func ": {} < {}", bytes, sizeof(Tp)));            \
  123|      0|        }                                                                      \
  124|    444|        return *reinterpret_cast<Tp*>(std::data(c));                           \
  125|    444|    }
_ZN7stdplus3raw8copyFromITkNS_17TriviallyCopyableE21payload_update_statusTkNS0_6detail15ContainsTrivialENSt3__14spanIKhLm18446744073709551615EEEEET_RKT0_:
   81|    572|    {                                                                          \
   82|    572|        T ret;                                                                 \
   83|    572|        const size_t bytes = std::size(c) * sizeof(*std::data(c));             \
   84|    572|        if (bytes comp sizeof(ret))                                            \
  ------------------
  |  Branch (84:13): [True: 572, False: 0]
  ------------------
   85|    572|        {                                                                      \
   86|    572|            throw exception::Incomplete(                                       \
   87|    572|                std::format(#func ": {} < {}", bytes, sizeof(ret)));           \
   88|    572|        }                                                                      \
   89|    572|        const auto c_bytes = reinterpret_cast<const std::byte*>(std::data(c)); \
   90|      0|        const auto ret_bytes = reinterpret_cast<std::byte*>(&ret);             \
   91|      0|        std::copy(c_bytes, c_bytes + sizeof(ret), ret_bytes);                  \
   92|      0|        return ret;                                                            \
   93|    572|    }
_ZN7stdplus3raw7extractIN6google4hoth8internal9RspHeaderETkNS_17TriviallyCopyableEKhEET_RNSt3__14spanIT0_Lm18446744073709551615EEE:
  146|  25.3M|{
  147|  25.3M|    T ret = copyFrom<T>(data);
  148|  25.3M|    static_assert(sizeof(T) % sizeof(IntT) == 0);
  149|  25.3M|    data = data.subspan(sizeof(T) / sizeof(IntT));
  150|  25.3M|    return ret;
  151|  25.3M|}
_ZN7stdplus3raw8copyFromITkNS_17TriviallyCopyableEN6google4hoth8internal9RspHeaderETkNS0_6detail15ContainsTrivialENSt3__14spanIKhLm18446744073709551615EEEEET_RKT0_:
   81|  25.3M|    {                                                                          \
   82|  25.3M|        T ret;                                                                 \
   83|  25.3M|        const size_t bytes = std::size(c) * sizeof(*std::data(c));             \
   84|  25.3M|        if (bytes comp sizeof(ret))                                            \
  ------------------
  |  Branch (84:13): [True: 0, False: 25.3M]
  ------------------
   85|  25.3M|        {                                                                      \
   86|      0|            throw exception::Incomplete(                                       \
   87|      0|                std::format(#func ": {} < {}", bytes, sizeof(ret)));           \
   88|      0|        }                                                                      \
   89|  25.3M|        const auto c_bytes = reinterpret_cast<const std::byte*>(std::data(c)); \
   90|  25.3M|        const auto ret_bytes = reinterpret_cast<std::byte*>(&ret);             \
   91|  25.3M|        std::copy(c_bytes, c_bytes + sizeof(ret), ret_bytes);                  \
   92|  25.3M|        return ret;                                                            \
   93|  25.3M|    }
_ZN7stdplus3raw8copyFromITkNS_17TriviallyCopyableE31payload_update_confirm_responseTkNS0_6detail15ContainsTrivialENSt3__14spanIKhLm18446744073709551615EEEEET_RKT0_:
   81|    687|    {                                                                          \
   82|    687|        T ret;                                                                 \
   83|    687|        const size_t bytes = std::size(c) * sizeof(*std::data(c));             \
   84|    687|        if (bytes comp sizeof(ret))                                            \
  ------------------
  |  Branch (84:13): [True: 687, False: 0]
  ------------------
   85|    687|        {                                                                      \
   86|    687|            throw exception::Incomplete(                                       \
   87|    687|                std::format(#func ": {} < {}", bytes, sizeof(ret)));           \
   88|    687|        }                                                                      \
   89|    687|        const auto c_bytes = reinterpret_cast<const std::byte*>(std::data(c)); \
   90|      0|        const auto ret_bytes = reinterpret_cast<std::byte*>(&ret);             \
   91|      0|        std::copy(c_bytes, c_bytes + sizeof(ret), ret_bytes);                  \
   92|      0|        return ret;                                                            \
   93|    687|    }

_ZN7stdplus6detail8StrBufASIcLm128ENSt3__19allocatorIcEEE6inlLenEh:
  100|  95.2k|    {
  101|  95.2k|        store.inl.len = len;
  102|  95.2k|    }
_ZN7stdplus6detail8StrBufASIcLm128ENSt3__19allocatorIcEEE8zeroInitEv:
  118|  1.52k|    {
  119|  1.52k|        if (std::is_constant_evaluated())
  ------------------
  |  Branch (119:13): [Folded, False: 1.52k]
  ------------------
  120|      0|        {
  121|      0|            store.dyn.ptr = allocate(buf_len);
  122|      0|            store.dyn.cap = buf_len;
  123|      0|            dynLen(0);
  124|      0|        }
  125|  1.52k|        else
  126|  1.52k|        {
  127|  1.52k|            inlLen(0);
  128|  1.52k|        }
  129|  1.52k|    }
_ZNK7stdplus6detail8StrBufASIcLm128ENSt3__19allocatorIcEEE5isDynEv:
   76|  98.3k|    {
   77|  98.3k|        if (std::is_constant_evaluated())
  ------------------
  |  Branch (77:13): [Folded, False: 98.3k]
  ------------------
   78|      0|        {
   79|      0|            return true;
   80|      0|        }
   81|  98.3k|        return store.inl.len & inl_mask;
   82|  98.3k|    }
_ZNK7stdplus6detail8StrBufASIcLm128ENSt3__19allocatorIcEEE6inlLenEv:
   95|  95.2k|    {
   96|  95.2k|        return store.inl.len;
   97|  95.2k|    }
_ZN7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEE6appendEm:
  298|  93.7k|    {
  299|  93.7k|        if (!as.isDyn())
  ------------------
  |  Branch (299:13): [True: 93.7k, False: 0]
  ------------------
  300|  93.7k|        {
  301|  93.7k|            const std::size_t oldlen = as.inlLen();
  302|  93.7k|            const std::size_t newlen = oldlen + amt;
  303|  93.7k|            if (newlen <= as.buf_len)
  ------------------
  |  Branch (303:17): [True: 93.7k, False: 0]
  ------------------
  304|  93.7k|            {
  305|  93.7k|                as.inlLen(newlen);
  306|  93.7k|                return as.store.inl.ptr + oldlen;
  307|  93.7k|            }
  308|      0|            const std::size_t newcap = newlen + (newlen >> 1);
  309|      0|            const auto ptr = as.allocate(newcap);
  310|      0|            std::copy(as.store.inl.ptr, as.store.inl.ptr + oldlen, ptr);
  311|       |
  312|      0|            as.store.dyn.ptr = ptr;
  313|      0|            as.store.dyn.cap = newcap;
  314|      0|            as.dynLen(newlen);
  315|      0|            return ptr + oldlen;
  316|  93.7k|        }
  317|      0|        const std::size_t oldlen = as.dynLen();
  318|      0|        const std::size_t newlen = oldlen + amt;
  319|      0|        if (newlen > as.store.dyn.cap)
  ------------------
  |  Branch (319:13): [True: 0, False: 0]
  ------------------
  320|      0|        {
  321|      0|            const std::size_t newcap = newlen + (newlen >> 1);
  322|      0|            const auto ptr = as.allocate(newcap);
  323|      0|            std::copy(as.store.dyn.ptr, as.store.dyn.ptr + oldlen, ptr);
  324|      0|            as.deallocate(as.store.dyn.ptr, as.store.dyn.cap);
  325|       |
  326|      0|            as.store.dyn.ptr = ptr;
  327|      0|            as.store.dyn.cap = newcap;
  328|      0|        }
  329|      0|        as.dynLen(newlen);
  330|      0|        return as.store.dyn.ptr + oldlen;
  331|  93.7k|    }
_ZN7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEE9push_backEc:
  339|  93.7k|    {
  340|  93.7k|        *append(1) = c;
  341|  93.7k|    }
_ZNK7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEE4dataEv:
  373|  1.52k|    {
  374|  1.52k|        return as.isDyn() ? as.store.dyn.ptr : as.store.inl.ptr;
  ------------------
  |  Branch (374:16): [True: 0, False: 1.52k]
  ------------------
  375|  1.52k|    }
_ZNK7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEE5beginEv:
  383|  1.52k|    {
  384|  1.52k|        return data();
  385|  1.52k|    }
_ZNK7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEE4sizeEv:
  288|  1.52k|    {
  289|  1.52k|        return as.isDyn() ? as.dynLen() : as.inlLen();
  ------------------
  |  Branch (289:16): [True: 0, False: 1.52k]
  ------------------
  290|  1.52k|    }
_ZNK7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEEcvNS1_17basic_string_viewIcNS1_11char_traitsIcEEEEEv:
  293|  1.52k|    {
  294|  1.52k|        return std::basic_string_view<CharT>(begin(), size());
  295|  1.52k|    }
_ZN7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEEC2Ev:
  235|  1.52k|    constexpr BasicStrBuf() noexcept : as({}) {}
_ZN7stdplus6detail8StrBufASIcLm128ENSt3__19allocatorIcEEEC2EOS4_:
  131|  1.52k|    constexpr StrBufAS(Allocator&& a) noexcept : Allocator(std::move(a))
  132|  1.52k|    {
  133|  1.52k|        if (std::is_constant_evaluated())
  ------------------
  |  Branch (133:13): [Folded, False: 1.52k]
  ------------------
  134|      0|        {
  135|      0|            std::construct_at(&store.dyn);
  136|      0|        }
  137|  1.52k|        zeroInit();
  138|  1.52k|    }
_ZN7stdplus11BasicStrBufIcLm128ENSt3__19allocatorIcEEED2Ev:
  280|  1.52k|    {
  281|  1.52k|        if (as.isDyn())
  ------------------
  |  Branch (281:13): [True: 0, False: 1.52k]
  ------------------
  282|      0|        {
  283|      0|            as.deallocate(as.store.dyn.ptr, as.store.dyn.cap);
  284|      0|        }
  285|  1.52k|    }

_ZN7stdplus9exception10IncompleteC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   30|  1.25k|    std::system_error(std::make_error_code(std::errc::illegal_byte_sequence),
   31|  1.25k|                      what)
   32|  1.25k|{}

_ZN7stdplus6printsEP8_IO_FILENSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
    9|  1.52k|{
   10|  1.52k|    int r = std::fwrite(data.data(), sizeof(char), data.size(), stream);
   11|  1.52k|    if (r < 0)
  ------------------
  |  Branch (11:9): [True: 0, False: 1.52k]
  ------------------
   12|      0|    {
   13|       |        throw std::system_error(errno, std::generic_category());
   14|      0|    }
   15|  1.52k|}

