IterDataAt
Description
Pointer to the element at absolute index idx in the iterator’s backing region. Unlike IterPos, this is index-addressed (no dependency on pos / direction) and is well-defined at idx == length (returns the one-past-end pointer, the standard C idiom for a half-open upper bound). Use when you need to address a remembered position – e.g. the cursor saved before a parse attempt – without going through the cursor.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
MachO.c:185:
// plus the 16-byte segname plus the body.
IterMustMove(cmd, 8); // skip cmd(4) + cmdsize(4) prefix
MemCopy(seg.name, IterDataAt(cmd, IterIndex(cmd)), 16);
seg.name[16] = '\0';
IterMustMove(cmd, 16);- In
MachO.c:222:
MachoSection sec;
MemSet(&sec, 0, sizeof(sec));
MemCopy(sec.section, IterDataAt(&sec_it, IterIndex(&sec_it)), 16);
sec.section[16] = '\0';
IterMustMove(&sec_it, 16);- In
MachO.c:225:
sec.section[16] = '\0';
IterMustMove(&sec_it, 16);
MemCopy(sec.segment, IterDataAt(&sec_it, IterIndex(&sec_it)), 16);
sec.segment[16] = '\0';
IterMustMove(&sec_it, 16);- In
MachO.c:286:
// proves the 8-byte prefix plus the 16-byte UUID payload fit.
IterMustMove(cmd, 8); // skip cmd + cmdsize prefix
MemCopy(ctx->out->uuid, IterDataAt(cmd, IterIndex(cmd)), 16);
ctx->out->has_uuid = true;
return true;- In
Dwarf.c:160:
if (IterRemainingLength(cur) < out->std_opcode_lengths_count)
return false;
out->standard_opcode_lengths = IterDataAt(cur, IterIndex(cur));
// Must-precondition: the `IterRemainingLength < count` guard above
// proves the cursor has at least `count` bytes left in the buffer.
- In
Dwarf.c:164:
// proves the cursor has at least `count` bytes left in the buffer.
IterMustMove(cur, (i64)out->std_opcode_lengths_count);
out->strings_start = IterDataAt(cur, IterIndex(cur));
return true;
}- In
Dwarf.c:171:
// start of the line number program body.
static bool skip_line_program_tables(BufIter *cur) {
while (IterIndex(cur) < IterLength(cur) && *IterDataAt(cur, IterIndex(cur)) != 0) {
if (!BufReadZstr(cur))
return false;- In
Dwarf.c:180:
IterMustNext(cur); // empty terminator
while (IterIndex(cur) < IterLength(cur) && *IterDataAt(cur, IterIndex(cur)) != 0) {
if (!BufReadZstr(cur))
return false;- In
Dwarf.c:229:
static bool collect_cu_strings(BufIter cur, Str *pool, CuStrings *cs) {
// include_directories
while (IterIndex(&cur) < IterLength(&cur) && *IterDataAt(&cur, IterIndex(&cur)) != 0) {
Zstr dir = BufReadZstr(&cur);
if (!dir)- In
Dwarf.c:245:
// file_names
while (IterIndex(&cur) < IterLength(&cur) && *IterDataAt(&cur, IterIndex(&cur)) != 0) {
Zstr name = BufReadZstr(&cur);
if (!name)- In
Dwarf.c:344:
lnp_reset(&st, hdr->default_is_stmt);
while (IterDataAt(&cur, IterIndex(&cur)) < prog_end) {
u8 op = 0;
if (!BufReadU8(&cur, &op))- In
Dwarf.c:354:
if (!BufReadULeb128(&cur, &length))
return false;
if (length == 0 || (u64)(prog_end - IterDataAt(&cur, IterIndex(&cur))) < length)
return false;
const u8 *body_end = IterDataAt(&cur, IterIndex(&cur)) + length;- In
Dwarf.c:356:
if (length == 0 || (u64)(prog_end - IterDataAt(&cur, IterIndex(&cur))) < length)
return false;
const u8 *body_end = IterDataAt(&cur, IterIndex(&cur)) + length;
u8 sub_op = 0;
if (!BufReadU8(&cur, &sub_op))- In
Dwarf.c:369:
case DW_LNE_SET_ADDRESS :
// operand size = remaining body bytes; on x86-64 always 8.
if (body_end - IterDataAt(&cur, IterIndex(&cur)) == 8) {
if (!BufReadU64LE(&cur, &st.address))
return false;- In
Dwarf.c:372:
if (!BufReadU64LE(&cur, &st.address))
return false;
} else if (body_end - IterDataAt(&cur, IterIndex(&cur)) == 4) {
u32 a32 = 0;
if (!BufReadU32LE(&cur, &a32))- In
Dwarf.c:398:
// above proved `length <= prog_end - here`, and switch arms
// only consume bytes within the body. Jump to body_end.
IterMustMove(&cur, (i64)((size)(body_end - IterDataAt(&cur, 0)) - IterIndex(&cur)));
} else if (op < hdr->opcode_base) {
// Standard opcode
- In
Dwarf.c:564:
bool ok = true;
while (IterRemainingLength(§ion_cur) > 0) {
const u8 *unit_start = IterDataAt(§ion_cur, IterIndex(§ion_cur));
u32 unit_length = 0;
BufIter peek = section_cur;- In
Dwarf.c:602:
// String/program iters cover the bytes from `hdr.strings_start`
// up to the end of this CU.
size strings_start_pos = (size)(hdr.strings_start - IterDataAt(§ion_cur, 0));
BufIter str_cur = BufIterFromMemory(IterDataAt(§ion_cur, 0), unit_end_pos);
// strings_start_pos lies within `[0, unit_end_pos]` by construction
- In
Dwarf.c:603:
// up to the end of this CU.
size strings_start_pos = (size)(hdr.strings_start - IterDataAt(§ion_cur, 0));
BufIter str_cur = BufIterFromMemory(IterDataAt(§ion_cur, 0), unit_end_pos);
// strings_start_pos lies within `[0, unit_end_pos]` by construction
// -- `hdr.strings_start` was assigned from inside this section's
- In
Dwarf.c:615:
// Skip past the tables to find the program body start.
BufIter prog_anchor = BufIterFromMemory(IterDataAt(§ion_cur, 0), unit_end_pos);
// Must-precondition: same bounds proof as `str_cur` above --
// `strings_start_pos` is inside `[0, unit_end_pos]` by header
- In
DwarfInfo.c:594:
// info_cur position up to unit_end_pos).
BufIter die_cur =
BufIterFromMemory(IterDataAt(&info_cur, IterIndex(&info_cur)), unit_end_pos - IterIndex(&info_cur));
if (!walk_cu_dies(die_cur, &abbrevs, addr_size, str_bytes, str_size, &out->string_pool, &pending)) {
abbrev_table_deinit(&abbrevs);- In
Pdb.c:583:
continue;
}
Zstr name = (Zstr)IterDataAt(&body, IterIndex(&body));
(void)flags; // permissive: we don't filter by FUNCTION bit;
}
out->initial_instructions = IterDataAt(body, IterIndex(body));
out->initial_instructions_size = IterRemainingLength(body);
return true; u64 pc_begin = 0;
{
u64 here = eh_byte_vaddr(section_data, section_addr, IterDataAt(body, IterIndex(body)));
if (!decode_eh_ptr(body, cie->fde_pointer_encoding, here, &pc_begin))
return false; u64 pc_range = 0;
{
u64 here = eh_byte_vaddr(section_data, section_addr, IterDataAt(body, IterIndex(body)));
if (!decode_eh_ptr(body, range_enc, here, &pc_range))
return false; }
out->instructions = IterDataAt(body, IterIndex(body));
out->instructions_size = IterRemainingLength(body);
return true; BufIter section_cur = BufIterFromMemory(section_data, eh->size);
while (IterRemainingLength(§ion_cur) > 0) {
const u8 *rec_start = IterDataAt(§ion_cur, IterIndex(§ion_cur));
u32 length32 = 0;
if (!BufReadU32LE(§ion_cur, &length32)) // 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(IterDataAt(§ion_cur, IterIndex(§ion_cur)), length32 - 4);
if (parse_cie(&body, cie_offset, &cie)) {
if (!VecPushBackR(&out->cies, cie)) { u64 cie_offset = id_field_off - (u64)id;
DwarfFde fde;
BufIter body = BufIterFromMemory(IterDataAt(§ion_cur, IterIndex(§ion_cur)), length32 - 4);
if (parse_fde(&body, rec_start, cie_offset, out, section_data, eh->addr, &fde)) {
if (!VecPushBackR(&out->fdes, fde)) {- In
Dns.c:111:
u64 label_idx = 0;
while (cur < IterLength(it)) {
u8 b = *IterDataAt(it, cur);
if (b == 0) {
++cur;- In
Dns.c:129:
return false;
}
u16 ptr = (u16)(((b & 0x3Fu) << 8) | *IterDataAt(it, cur + 1));
if (!jumped) {
// First jump: linear cursor advances past the 2-byte
- In
Dns.c:163:
}
for (u64 i = 0; i < label_len; ++i) {
StrPushBackR(out_name, (char)*IterDataAt(it, cur + 1 + i));
}
name_len += label_len;- In
Dns.c:201:
// Stash raw rdata.
if (!BufPushBytes(&rec->rdata, IterDataAt(it, rdata_start), rdlength)) {
return false;
}- In
Dns.c:212:
}
for (u64 i = 0; i < 4; ++i) {
rec->ipv4[i] = *IterDataAt(it, rdata_start + i);
}
break;- In
Dns.c:220:
}
for (u64 i = 0; i < 16; ++i) {
rec->ipv6[i] = *IterDataAt(it, rdata_start + i);
}
break;- In
Pe.c:209:
ctx->num_sections = num_sec;
ctx->opt_hdr_size = size_opt;
*out_opt_offset = (u64)(IterDataAt(&c, IterIndex(&c)) - BufData(&ctx->out->data));
return true;
}- In
Pe.c:386:
// 8-byte name: bytes, not a numeric, so copy + advance manually.
// IterRemainingLength >= 40 bound above proves 8 bytes are live.
MemCopy(s.name, IterDataAt(&c, IterIndex(&c)), 8);
s.name[8] = '\0';
IterMustMove(&c, 8);- In
Pe.c:477:
continue;
// Same proof: 16 bytes are live.
MemCopy(cv->guid, IterDataAt(&cv_cur, IterIndex(&cv_cur)), 16);
IterMustMove(&cv_cur, 16);
if (!BufReadU32LE(&cv_cur, &cv->age))- In
Pe.c:482:
continue;
// Verify the trailing path is NUL-terminated inside the record.
const u8 *path_start = IterDataAt(&cv_cur, IterIndex(&cv_cur));
const u8 *region_end = IterDataAt(&cv_cur, IterLength(&cv_cur));
bool terminated = false;- In
Pe.c:483:
// Verify the trailing path is NUL-terminated inside the record.
const u8 *path_start = IterDataAt(&cv_cur, IterIndex(&cv_cur));
const u8 *region_end = IterDataAt(&cv_cur, IterLength(&cv_cur));
bool terminated = false;
for (const u8 *p = path_start; p < region_end; ++p) {- In
StrIter.h:224:
/// TAGS: StrIter, Position, Alias
///
#define StrIterDataAt(mi, idx) IterDataAt((mi), (idx))
// ---------------------------------------------------------------------------
Last updated on