Skip to content
BufIterFromMemory

BufIterFromMemory

Description

Construct a BufIter over [data, data + length).

Usage example (Cross-references)

Usage examples (Cross-references)
    bool test_byte_iter_from_memory(void) {
        const u8 bytes[] = {0xAA, 0xBB, 0xCC};
        BufIter  it      = BufIterFromMemory(bytes, 3);
        u8       v;
        bool     ok = BufReadU8(&it, &v) && v == 0xAA;
        }
        u32     e_lfanew;
        BufIter c = BufIterFromMemory(ctx->out->data + DOS_E_LFANEW_OFFSET, ctx->out->data_size - DOS_E_LFANEW_OFFSET);
        if (!BufReadU32LE(&c, &e_lfanew))
            return false;
    // NT signature + File Header. Returns the offset of the Optional Header.
    static bool pe_decode_nt(PeContext *ctx, u64 *out_opt_offset) {
        BufIter c = BufIterFromMemory(ctx->out->data + ctx->nt_offset, ctx->out->data_size - ctx->nt_offset);
        u32     sig;
        if (!BufReadU32LE(&c, &sig) || sig != NT_SIGNATURE) {
            return false;
        }
        BufIter c = BufIterFromMemory(ctx->out->data + opt_offset, ctx->opt_hdr_size);
    
        u16 magic;
    static bool pe_decode_sections(PeContext *ctx, u64 opt_offset) {
        u64     sec_offset = opt_offset + ctx->opt_hdr_size;
        BufIter c          = BufIterFromMemory(ctx->out->data + sec_offset, ctx->out->data_size - sec_offset);
    
        for (u32 i = 0; i < ctx->num_sections; ++i) {
        for (u32 i = 0; i < num_entries; ++i) {
            u64     entry_off = dir_offset + (u64)i * DEBUG_ENTRY_SIZE;
            BufIter c         = BufIterFromMemory(ctx->out->data + entry_off, ctx->out->data_size - entry_off);
            u32     charac, ts, type, sz, raddr, rptr;
            u16     ver_maj, ver_min;
            if (sz < 4 + 16 + 4 + 1)
                continue;
            BufIter cv_cur = BufIterFromMemory(ctx->out->data + rptr, sz);
            u32     cv_sig;
            if (!BufReadU32LE(&cv_cur, &cv_sig))
        PeContext ctx = {
            .out  = out,
            .file = BufIterFromMemory(data, data_size),
        };
            return false;
        }
        BufIter it = BufIterFromMemory(buf, len);
        u16     flags, qd, an, ns, ar;
        if (!BufReadFmt(&it, "{>2r}{>2r}{>2r}{>2r}{>2r}{>2r}", out->id, flags, qd, an, ns, ar)) {
            return false;
        }
        BufIter sb = BufIterFromMemory(self->data + 32, self->data_size - 32);
        u32     free_blk, num_blocks, unknown;
        if (!BufReadFmt(
            return false;
        }
        BufIter dir_iter = BufIterFromMemory(self->stream_dir, self->stream_dir_size);
        if (!BufReadU32LE(&dir_iter, &self->num_streams))
            return false;
        if (!stream_read(self, 1, 0, buf, sizeof(buf)))
            return false;
        BufIter bi = BufIterFromMemory(buf, sizeof(buf));
        if (!BufReadFmt(&bi, FMT_PDB_INFO_LE, self->info.version, self->info.signature, self->info.age)) {
            LOG_ERROR("PDB: info stream prefix truncated");
            return r;
    
        BufIter bi = BufIterFromMemory(hdr, DBI_HEADER_SIZE);
        u32 version_sig, version_hdr, age, mod_size, seccontrib, secmap, srcinfo, tsm, mfc_tsm_idx, optdbg_size, ec_size,
            padding;
        for (u32 i = 0; i < n; ++i) {
            // IMAGE_SECTION_HEADER: name[8] + VirtualSize(4) + VirtualAddress(4) + ...
            BufIter rec = BufIterFromMemory(buf + i * 40 + 8, 40 - 8);
            (void)BufReadU32LE(&rec, &out[i].virtual_size);
            (void)BufReadU32LE(&rec, &out[i].virtual_address);
                // Record body starts at cur + 4 (past len + kind). 10-byte
                // prefix (Flags/Offset/Segment) then NUL-terminated Name.
                BufIter body = BufIterFromMemory(buf + cur + 4, rec_len - 2);
                u32     flags, offset;
                u16     segment;
        U64Vec pending_dir_offsets  = VecInitT(pending_dir_offsets, alloc);
    
        BufIter section_cur = BufIterFromMemory(elf->data + line_section->offset, line_section->size);
    
        bool ok = true;
            // up to the end of this CU.
            size    strings_start_pos = (size)(hdr.strings_start - section_cur.data);
            BufIter str_cur           = BufIterFromMemory(section_cur.data, unit_end_pos);
            str_cur.pos               = strings_start_pos;
            if (!collect_cu_strings(str_cur, &out->string_pool, &cs)) {
    
            // Skip past the tables to find the program body start.
            BufIter prog_anchor = BufIterFromMemory(section_cur.data, unit_end_pos);
            prog_anchor.pos     = strings_start_pos;
            if (!skip_line_program_tables(&prog_anchor)) {
        const u8 *section_data = elf->data + eh->offset;
    
        BufIter section_cur = BufIterFromMemory(section_data, eh->size);
        while (IterRemainingLength(&section_cur) > 0) {
            const u8 *rec_start = section_cur.data + section_cur.pos;
                // Body iter starts just after the id field (since parse_cie
                // doesn't re-read id) and spans the remainder of the record.
                BufIter body = BufIterFromMemory(section_cur.data + section_cur.pos, length32 - 4);
                if (parse_cie(&body, cie_offset, &cie)) {
                    if (!VecPushBackR(&out->cies, cie)) {
                u64      cie_offset   = id_field_off - id;
                DwarfFde fde;
                BufIter  body = BufIterFromMemory(section_cur.data + section_cur.pos, length32 - 4);
                if (parse_fde(&body, rec_start, cie_offset, out, section_data, eh->addr, &fde)) {
                    if (!VecPushBackR(&out->fdes, fde)) {
    
    static bool cfi_vm_run(CfiVm *vm, const u8 *insns, u64 insns_size, u64 stop_at) {
        BufIter cur      = BufIterFromMemory(insns, insns_size);
        bool    stop_now = false;
        while (IterRemainingLength(&cur) > 0) {
        }
    
        BufIter info_cur = BufIterFromMemory(info_bytes, info_size);
    
        PendingFns pending = VecInitT(pending, alloc);
    
            AbbrevTable abbrevs;
            BufIter     abbrev_cur = BufIterFromMemory(abbrev_bytes + abbrev_offset, abbrev_size - abbrev_offset);
            if (!parse_abbrev_table(abbrev_cur, &abbrevs, alloc)) {
                ok = false;
            // DIE iter spans the DIE body within this CU (from current
            // info_cur position up to unit_end_pos).
            BufIter die_cur = BufIterFromMemory(info_cur.data + info_cur.pos, unit_end_pos - info_cur.pos);
            if (!walk_cu_dies(die_cur, &abbrevs, addr_size, str_bytes, str_size, &out->string_pool, &pending)) {
                abbrev_table_deinit(&abbrevs);
            return false;
        }
        BufIter c = BufIterFromMemory(m->data, m->data_size);
        u32     magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags, reserved;
        if (!BufReadFmt(
        // cmd_p layout: cmd(4) cmdsize(4) segname[16] then FMT_MACHO_SEGMENT64_BODY_LE.
        copy_fixed16(seg.name, cmd_p + 8);
        BufIter c = BufIterFromMemory(cmd_p + 24, cmdsize - 24);
        u32     maxprot, initprot;
        if (!BufReadFmt(
            copy_fixed16(sec.section, s + 0);
            copy_fixed16(sec.segment, s + 16);
            BufIter sc = BufIterFromMemory(s + 32, SECT64_SIZE - 32);
            u32     align, reloff, nreloc, reserved1, reserved2, reserved3;
            if (!BufReadFmt(
            return false;
        }
        BufIter c = BufIterFromMemory(cmd_p + 8, cmdsize - 8);
        if (!BufReadFmt(&c, FMT_MACHO_SYMTAB_BODY_LE, ctx->symoff, ctx->nsyms, ctx->stroff, ctx->strsize)) {
            LOG_ERROR("MachO: LC_SYMTAB body truncated");
                return false;
            const u8 *cmd_p = ctx->out->data + cur;
            BufIter   pc    = BufIterFromMemory(cmd_p, end - cur);
            u32       cmd, cmdsize;
            if (!BufReadFmt(&pc, FMT_MACHO_LC_PREFIX_LE, cmd, cmdsize)) {
        }
        const u8 *str_base = ctx->out->data + ctx->stroff;
        BufIter   tab      = BufIterFromMemory(ctx->out->data + ctx->symoff, (u64)ctx->nsyms * NLIST64_SIZE);
        for (u32 i = 0; i < ctx->nsyms; ++i) {
            u32 n_strx;
    
    /// Construct a BufIter over a Buf's bytes.
    #define BufIterFromBuf(b_) BufIterFromMemory((const u8 *)(b_)->data, (b_)->length)
    
    // ---------------------------------------------------------------------------
Last updated on