simplified dwarf parsing checkpoint: pull out form value reading, line table header parsing

This commit is contained in:
Ryan Fleury
2025-11-11 16:27:16 -08:00
parent b8a8ec31c7
commit faee02f763
3 changed files with 536 additions and 160 deletions
+449 -145
View File
@@ -239,11 +239,176 @@ dw2_abbrev_map_from_data(Arena *arena, String8 data, U64 off)
return map;
}
////////////////////////////////
//~ rjf: Form Value Parsing
internal U64
dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out)
{
U64 start_off = off;
DW2_FormVal val = {0};
{
U64 bytes_to_read = 0;
switch(form_kind)
{
//- rjf: no-ops
default:
case DW_Form_Indirect:
case DW_Form_Null:
{}break;
//- rjf: 1-byte uint reads
case DW_Form_Ref1:
case DW_Form_Data1:
case DW_Form_Flag:
case DW_Form_Strx1:
case DW_Form_Addrx1:
bytes_to_read = 1; goto read_fixed_uint;
//- rjf: 2-byte uint reads
case DW_Form_Ref2:
case DW_Form_Data2:
case DW_Form_Strx2:
case DW_Form_Addrx2:
bytes_to_read = 2; goto read_fixed_uint;
//- rjf: 3-byte uint reads
case DW_Form_Strx3:
case DW_Form_Addrx3:
bytes_to_read = 3; goto read_fixed_uint;
//- rjf: 4-byte uint reads
case DW_Form_Data4:
case DW_Form_Ref4:
case DW_Form_RefSup4:
case DW_Form_Strx4:
case DW_Form_Addrx4:
bytes_to_read = 4; goto read_fixed_uint;
//- rjf: 8-byte uint reads
case DW_Form_Data8:
case DW_Form_Ref8:
case DW_Form_RefSig8:
case DW_Form_RefSup8:
bytes_to_read = 8; goto read_fixed_uint;
//- rjf: 16-byte uint reads
case DW_Form_Data16:
bytes_to_read = 16; goto read_fixed_uint;
//- rjf: address-sized reads
case DW_Form_Addr:
bytes_to_read = ctx->addr_size; goto read_fixed_uint;
//- rjf: format-defined-size reads
case DW_Form_RefAddr:
case DW_Form_SecOffset:
case DW_Form_LineStrp:
case DW_Form_Strp:
case DW_Form_StrpSup:
bytes_to_read = dw_size_from_format(ctx->format); goto read_fixed_uint;
//- rjf: fixed-size uint reads
read_fixed_uint:
{
off += str8_deserial_read(data, off, &val.u128.u64[0], bytes_to_read, bytes_to_read);
}break;
//- rjf: uleb128 reads
case DW_Form_UData:
case DW_Form_RefUData:
case DW_Form_Strx:
case DW_Form_Addrx:
case DW_Form_LocListx:
case DW_Form_RngListx:
{
off += str8_deserial_read_uleb128(data, off, &val.u128.u64[0]);
}break;
//- rjf: sleb128 reads
case DW_Form_SData:
{
off += str8_deserial_read_sleb128(data, off, &val.u128.u64[0]);
}break;
//- rjf: fixed-size uint reads / skips
case DW_Form_Block1: bytes_to_read = 1; goto read_fixed_uint_and_skip;
case DW_Form_Block2: bytes_to_read = 2; goto read_fixed_uint_and_skip;
case DW_Form_Block4: bytes_to_read = 4; goto read_fixed_uint_and_skip;
read_fixed_uint_and_skip:
{
U64 size = 0;
U64 og_read_off = off;
off += str8_deserial_read(data, off, &size, bytes_to_read, bytes_to_read);
val.u128.u64[0] = size;
val.u128.u64[1] = og_read_off;
off += size;
}break;
//- rjf: uleb128 read & skip
case DW_Form_Block:
{
U64 size = 0;
U64 og_read_off = off;
off += str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = size;
val.u128.u64[1] = og_read_off;
off += size;
}break;
//- rjf: strings
case DW_Form_String:
{
String8 string = {0};
U64 og_read_off = off;
off += str8_deserial_read_cstr(data, off, &string);
val.u128.u64[0] = og_read_off;
val.u128.u64[1] = og_read_off + string.size - 1;
}break;
//- rjf: implicit constants (no reading in .debug_info; value comes from .debug_abbrev)
case DW_Form_ImplicitConst:
{
val.u128.u64[0] = implicit_const;
}break;
//- rjf: exprloc
case DW_Form_ExprLoc:
{
U64 size = 0;
U64 og_read_off = off;
U64 bytes_read = str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = og_read_off + bytes_read;
val.u128.u64[1] = size;
off += bytes_read;
}break;
//- rjf: flag present
case DW_Form_FlagPresent:
{
val.u128.u64[0] = 1;
}break;
}
}
*out = val;
U64 bytes_read = (off - start_off);
return bytes_read;
}
internal String8
dw2_string_from_form_val(DW2_ParseCtx *ctx, DW2_FormVal val)
{
String8 section_data = ctx->raw->sec[val.section_kind].data;
Rng1U64 range = r1u64(val.u128.u64[0], val.u128.u64[1]);
String8 string = str8_substr(section_data, range);
return string;
}
////////////////////////////////
//~ rjf: Tag Parsing
internal U64
dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out)
dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out)
{
U64 start_off = off;
@@ -272,7 +437,7 @@ dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag
U8 has_children = 0;
U64 attrib_abbrev_read_off = 0;
{
String8 abbrev_data = ctx->abbrev_data;
String8 abbrev_data = ctx->raw->sec[DW_Section_Abbrev].data;
U64 abbrev_read_off = abbrev_off;
U64 id = 0;
abbrev_read_off += str8_deserial_read_uleb128(abbrev_data, abbrev_read_off, &id);
@@ -288,7 +453,7 @@ dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag
DW2_AttribList attribs = {0};
if(abbrev_id != 0)
{
String8 abbrev_data = ctx->abbrev_data;
String8 abbrev_data = ctx->raw->sec[DW_Section_Abbrev].data;
U64 abbrev_read_off = attrib_abbrev_read_off;
for(;;)
{
@@ -312,150 +477,10 @@ dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag
}
// rjf: read attribute's value from .debug_info
DW2_AttribVal val = {0};
DW2_FormVal val = {0};
if(attrib_kind != 0)
{
U64 bytes_to_read = 0;
switch(attrib_form_kind)
{
//- rjf: no-ops
default:
case DW_Form_Indirect:
case DW_Form_Null:
{}break;
//- rjf: 1-byte uint reads
case DW_Form_Ref1:
case DW_Form_Data1:
case DW_Form_Flag:
case DW_Form_Strx1:
case DW_Form_Addrx1:
bytes_to_read = 1; goto read_fixed_uint;
//- rjf: 2-byte uint reads
case DW_Form_Ref2:
case DW_Form_Data2:
case DW_Form_Strx2:
case DW_Form_Addrx2:
bytes_to_read = 2; goto read_fixed_uint;
//- rjf: 3-byte uint reads
case DW_Form_Strx3:
case DW_Form_Addrx3:
bytes_to_read = 3; goto read_fixed_uint;
//- rjf: 4-byte uint reads
case DW_Form_Data4:
case DW_Form_Ref4:
case DW_Form_RefSup4:
case DW_Form_Strx4:
case DW_Form_Addrx4:
bytes_to_read = 4; goto read_fixed_uint;
//- rjf: 8-byte uint reads
case DW_Form_Data8:
case DW_Form_Ref8:
case DW_Form_RefSig8:
case DW_Form_RefSup8:
bytes_to_read = 8; goto read_fixed_uint;
//- rjf: 16-byte uint reads
case DW_Form_Data16:
bytes_to_read = 16; goto read_fixed_uint;
//- rjf: address-sized reads
case DW_Form_Addr:
bytes_to_read = ctx->addr_size; goto read_fixed_uint;
//- rjf: format-defined-size reads
case DW_Form_RefAddr:
case DW_Form_SecOffset:
case DW_Form_LineStrp:
case DW_Form_Strp:
case DW_Form_StrpSup:
bytes_to_read = dw_size_from_format(ctx->format); goto read_fixed_uint;
//- rjf: fixed-size uint reads
read_fixed_uint:
{
off += str8_deserial_read(data, off, &val.u128.u64[0], bytes_to_read, bytes_to_read);
}break;
//- rjf: uleb128 reads
case DW_Form_UData:
case DW_Form_RefUData:
case DW_Form_Strx:
case DW_Form_Addrx:
case DW_Form_LocListx:
case DW_Form_RngListx:
{
off += str8_deserial_read_uleb128(data, off, &val.u128.u64[0]);
}break;
//- rjf: sleb128 reads
case DW_Form_SData:
{
off += str8_deserial_read_sleb128(data, off, &val.u128.u64[0]);
}break;
//- rjf: fixed-size uint reads / skips
case DW_Form_Block1: bytes_to_read = 1; goto read_fixed_uint_and_skip;
case DW_Form_Block2: bytes_to_read = 2; goto read_fixed_uint_and_skip;
case DW_Form_Block4: bytes_to_read = 4; goto read_fixed_uint_and_skip;
read_fixed_uint_and_skip:
{
U64 size = 0;
U64 og_read_off = off;
off += str8_deserial_read(data, off, &size, bytes_to_read, bytes_to_read);
val.u128.u64[0] = size;
val.u128.u64[1] = og_read_off;
off += size;
}break;
//- rjf: uleb128 read & skip
case DW_Form_Block:
{
U64 size = 0;
U64 og_read_off = off;
off += str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = size;
val.u128.u64[1] = og_read_off;
off += size;
}break;
//- rjf: strings
case DW_Form_String:
{
String8 string = {0};
U64 og_read_off = off;
off += str8_deserial_read_cstr(data, off, &string);
val.u128.u64[0] = og_read_off;
val.u128.u64[1] = og_read_off + string.size - 1;
}break;
//- rjf: implicit constants (no reading in .debug_info; value comes from .debug_abbrev)
case DW_Form_ImplicitConst:
{
val.u128.u64[0] = implicit_const;
}break;
//- rjf: exprloc
case DW_Form_ExprLoc:
{
U64 size = 0;
U64 og_read_off = off;
U64 bytes_read = str8_deserial_read_uleb128(data, off, &size);
val.u128.u64[0] = og_read_off + bytes_read;
val.u128.u64[1] = size;
off += bytes_read;
}break;
//- rjf: flag present
case DW_Form_FlagPresent:
{
val.u128.u64[0] = 1;
}break;
}
off += dw2_read_form_val(ctx, data, off, attrib_form_kind, implicit_const, &val);
}
// rjf: push
@@ -485,3 +510,282 @@ dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag
U64 bytes_read = (off - start_off);
return bytes_read;
}
////////////////////////////////
//~ rjf: Line Table Parsing
internal U64
dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_LineTableHeader *out)
{
Temp scratch = scratch_begin(&arena, 1);
U64 start_off = 0;
//////////////////////////////
//- rjf: read unit length
//
U64 unit_length = 0;
DW_Format format = DW_Format_32Bit;
off += dw2_read_initial_length(data, off, &unit_length, &format);
U64 off_opl = off + unit_length;
//////////////////////////////
//- rjf: read version
//
DW_Version version = DW_Version_Null;
off += str8_deserial_read_struct(data, off, &version);
//////////////////////////////
//- rjf: read address / segment selector sizes
//
U8 addr_size = 0;
U8 segment_selector_size = 0;
switch(version)
{
// NOTE(rjf): pre-dwarf5: assume from context
default:
{
addr_size = ctx->addr_size;
}break;
// NOTE(rjf): @dwarf5 read address / segment selector sizes explicitly
case DW_Version_5:
{
off += str8_deserial_read_struct(data, off, &addr_size);
off += str8_deserial_read_struct(data, off, &segment_selector_size);
}break;
}
//////////////////////////////
//- rjf: read all remaining flat header properties
//
U64 header_length = 0;
U8 min_inst_length = 0;
U8 max_ops_per_inst = 1;
U8 default_is_stmt = 0;
S8 line_base = 0;
U8 line_range = 0;
U8 opcode_base = 0;
{
off += dw2_read_fmt_u64(data, off, format, &header_length);
off += str8_deserial_read_struct(data, off, &min_inst_length);
off += str8_deserial_read_struct(data, off, &max_ops_per_inst);
off += str8_deserial_read_struct(data, off, &default_is_stmt);
off += str8_deserial_read_struct(data, off, &line_base);
off += str8_deserial_read_struct(data, off, &line_range);
off += str8_deserial_read_struct(data, off, &opcode_base);
}
//////////////////////////////
//- rjf: read opcode lengths
//
U64 opcode_lengths_count = (opcode_base > 0 ? opcode_base - 1 : 0);
U8 *opcode_lengths = 0;
if(opcode_lengths_count > 0)
{
opcode_lengths = str8_skip(data, off).str;
off += sizeof(opcode_lengths[0]) * opcode_lengths_count;
}
//////////////////////////////
//- rjf: read directory / file tables
//
DW2_LineTableFileArray dirs = {0};
DW2_LineTableFileArray files = {0};
switch(version)
{
////////////////////////////
//- rjf: pre-dwarf5: simple(r) well-defined format... still ulebs everywhere but oh well...
// just wait until the next case...
//
default:
{
//- rjf: gather directories
DW2_LineTableFileList dir_list = {0};
{
// rjf: push compile directory as first list element, always
{
DW2_LineTableFileNode *n = push_array(scratch.arena, DW2_LineTableFileNode, 1);
SLLQueuePush(dir_list.first, dir_list.last, n);
dir_list.count += 1;
n->v.file_name = ctx->unit_dir;
}
// rjf: gather additional directories
for(;off < off_opl;)
{
String8 dir = {0};
off += str8_deserial_read_cstr(data, off, &dir);
if(dir.size != 0)
{
DW2_LineTableFileNode *n = push_array(scratch.arena, DW2_LineTableFileNode, 1);
SLLQueuePush(dir_list.first, dir_list.last, n);
dir_list.count += 1;
n->v.file_name = dir;
}
else
{
break;
}
}
}
//- rjf: gather files
DW2_LineTableFileList file_list = {0};
{
// rjf: push main compilation unit file as first list element, always
{
DW2_LineTableFileNode *n = push_array(scratch.arena, DW2_LineTableFileNode, 1);
SLLQueuePush(file_list.first, file_list.last, n);
file_list.count += 1;
n->v.file_name = ctx->unit_file;
}
// rjf: gather additional files
for(;off < off_opl;)
{
String8 file_name = {0};
U64 dir_idx = 0;
U64 modify_time = 0;
U64 file_size = 0;
off += str8_deserial_read_cstr(data, off, &file_name);
off += str8_deserial_read_uleb128(data, off, &dir_idx);
off += str8_deserial_read_uleb128(data, off, &modify_time);
off += str8_deserial_read_uleb128(data, off, &file_size);
if(file_name.size != 0)
{
DW2_LineTableFileNode *n = push_array(scratch.arena, DW2_LineTableFileNode, 1);
SLLQueuePush(file_list.first, file_list.last, n);
file_list.count += 1;
n->v.file_name = file_name;
n->v.dir_idx = dir_idx;
n->v.modify_time = modify_time;
n->v.file_size = file_size;
}
}
}
//- rjf: flatten
{
dirs.count = dir_list.count;
dirs.v = push_array(arena, DW2_LineTableFile, dirs.count);
files.count = file_list.count;
files.v = push_array(arena, DW2_LineTableFile, files.count);
{
U64 idx = 0;
for EachNode(n, DW2_LineTableFileNode, dir_list.first)
{
MemoryCopyStruct(&dirs.v[idx], &n->v);
idx += 1;
}
}
{
U64 idx = 0;
for EachNode(n, DW2_LineTableFileNode, file_list.first)
{
MemoryCopyStruct(&files.v[idx], &n->v);
idx += 1;
}
}
}
}break;
////////////////////////////
//- rjf: @dwarf5: another VM! d'oh. :(
//
case DW_Version_5:
{
//- rjf: read directory & file tables
for(B32 files = 0, dirs = 1; files <= 1; files = 1, dirs = 0)
{
// rjf: read header
U8 entry_formats_count = 0;
off += str8_deserial_read_struct(data, off, &entry_formats_count);
U64 *entry_formats = push_array(scratch.arena, U64, entry_formats_count*2);
for EachIndex(idx, entry_formats_count)
{
off += str8_deserial_read_uleb128(data, off, &entry_formats[idx]);
}
U64 table_count = 0;
off += str8_deserial_read_uleb128(data, off, &table_count);
// rjf: read all table entries
DW2_LineTableFileArray table = {0};
table.count = table_count;
table.v = push_array(arena, DW2_LineTableFile, table.count);
{
U64 idx = 0;
for(;off < off_opl && idx < table.count; idx += 1)
{
DW2_LineTableFile *entry_out = &table.v[idx];
for(U64 entry_format_idx = 0; entry_format_idx < entry_formats_count; entry_format_idx += 1)
{
DW_LNCT lnct = (DW_LNCT)entry_formats[entry_format_idx*2 + 0];
DW_FormKind form_kind = (DW_FormKind)entry_formats[entry_format_idx*2 + 1];
DW2_FormVal form_val = {0};
off += dw2_read_form_val(ctx, data, off, form_kind, 0, &form_val);
switch(lnct)
{
default:
{
log_infof("DWARF LNCT encoding not currently supported (0x%I64x).\n", (U64)lnct);
}break;
case DW_LNCT_Path:
{
entry_out->file_name = dw2_string_from_form_val(ctx, form_val);
}break;
case DW_LNCT_DirectoryIndex:
{
entry_out->dir_idx = form_val.u128.u64[0];
}break;
case DW_LNCT_TimeStamp:
{
entry_out->modify_time = form_val.u128.u64[0];
}break;
case DW_LNCT_Size:
{
entry_out->file_size = form_val.u128.u64[0];
}break;
case DW_LNCT_MD5:
{
entry_out->md5.u128 = form_val.u128;
}break;
case DW_LNCT_LLVM_Source:
{
entry_out->source = dw2_string_from_form_val(ctx, form_val);
}break;
}
}
}
}
}
}break;
}
//////////////////////////////
//- rjf: fill output
//
if(out)
{
out->unit_length = unit_length;
out->format = format;
out->version = version;
out->addr_size = addr_size;
out->segment_selector_size = segment_selector_size;
out->header_length = header_length;
out->min_inst_length = min_inst_length;
out->max_ops_per_inst = max_ops_per_inst;
out->default_is_stmt = default_is_stmt;
out->line_base = line_base;
out->line_range = line_range;
out->opcode_base = opcode_base;
out->opcode_lengths_count = opcode_lengths_count;
out->opcode_lengths = opcode_lengths;
out->dirs = dirs;
out->files = files;
}
U64 bytes_read = (off - start_off);
scratch_end(scratch);
return bytes_read;
}
+80 -8
View File
@@ -37,23 +37,27 @@ struct DW2_AbbrevMap
};
////////////////////////////////
//~ rjf: Tag Parsing Context
//~ rjf: Parsing Context Bundle
typedef struct DW2_TagParseCtx DW2_TagParseCtx;
struct DW2_TagParseCtx
typedef struct DW2_ParseCtx DW2_ParseCtx;
struct DW2_ParseCtx
{
DW_Raw *raw;
// NOTE(rjf): all subsequent fields optional - top-level code fills out whatever
// it can from context.
DW_Version version;
DW_Format format;
U64 addr_size;
String8 abbrev_data;
DW2_AbbrevMap *abbrev_map;
String8 unit_dir;
String8 unit_file;
};
////////////////////////////////
//~ rjf: Tag Attributes
typedef struct DW2_AttribVal DW2_AttribVal;
struct DW2_AttribVal
typedef struct DW2_FormVal DW2_FormVal;
struct DW2_FormVal
{
DW_SectionKind section_kind;
U128 u128;
@@ -64,7 +68,7 @@ struct DW2_Attrib
{
DW_AttribKind attrib_kind;
DW_FormKind form_kind;
DW2_AttribVal val;
DW2_FormVal val;
};
typedef struct DW2_AttribNode DW2_AttribNode;
@@ -93,6 +97,63 @@ struct DW2_Tag
DW2_AttribList attribs;
};
////////////////////////////////
//~ rjf: Line Info
typedef struct DW2_LineTableFile DW2_LineTableFile;
struct DW2_LineTableFile
{
String8 file_name;
U64 dir_idx;
U64 modify_time;
U64 file_size;
MD5 md5;
String8 source;
};
typedef struct DW2_LineTableFileNode DW2_LineTableFileNode;
struct DW2_LineTableFileNode
{
DW2_LineTableFileNode *next;
DW2_LineTableFile v;
};
typedef struct DW2_LineTableFileList DW2_LineTableFileList;
struct DW2_LineTableFileList
{
DW2_LineTableFileNode *first;
DW2_LineTableFileNode *last;
U64 count;
};
typedef struct DW2_LineTableFileArray DW2_LineTableFileArray;
struct DW2_LineTableFileArray
{
DW2_LineTableFile *v;
U64 count;
};
typedef struct DW2_LineTableHeader DW2_LineTableHeader;
struct DW2_LineTableHeader
{
U64 unit_length;
DW_Format format;
DW_Version version;
U8 addr_size;
U8 segment_selector_size;
U64 header_length;
U8 min_inst_length;
U8 max_ops_per_inst;
U8 default_is_stmt;
S8 line_base;
U8 line_range;
U8 opcode_base;
U64 opcode_lengths_count;
U8 *opcode_lengths;
DW2_LineTableFileArray dirs;
DW2_LineTableFileArray files;
};
////////////////////////////////
//~ rjf: Basic Parsing Helpers
@@ -109,9 +170,20 @@ internal U64 dw2_read_unit_header(String8 data, U64 off, DW2_UnitHeader *out);
internal DW2_AbbrevMap dw2_abbrev_map_from_data(Arena *arena, String8 data, U64 off);
////////////////////////////////
//~ rjf: Form Value Parsing
internal U64 dw2_read_form_val(DW2_ParseCtx *ctx, String8 data, U64 off, DW_FormKind form_kind, U64 implicit_const, DW2_FormVal *out);
internal String8 dw2_string_from_form_val(DW2_ParseCtx *ctx, DW2_FormVal val);
////////////////////////////////
//~ rjf: Tag Parsing
internal U64 dw2_read_tag(Arena *arena, DW2_TagParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out);
internal U64 dw2_read_tag(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_Tag *tag_out);
////////////////////////////////
//~ rjf: Line Table Parsing
internal U64 dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_LineTableHeader *out);
#endif // DWARF_PARSE_2_H
+7 -7
View File
@@ -257,24 +257,24 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
lane_sync();
////////////////////////////
//- rjf: build per-unit tag parsing contexts
//- rjf: build per-unit parsing contexts
//
DW2_TagParseCtx *unit_tag_parse_ctxs = 0;
DW2_ParseCtx *unit_parse_ctxs = 0;
{
if(lane_idx() == 0)
{
unit_tag_parse_ctxs = push_array(scratch.arena, DW2_TagParseCtx, unit_count);
unit_parse_ctxs = push_array(scratch.arena, DW2_ParseCtx, unit_count);
}
lane_sync_u64(&unit_tag_parse_ctxs, 0);
lane_sync_u64(&unit_parse_ctxs, 0);
Rng1U64 range = lane_range(unit_count);
for EachInRange(unit_idx, range)
{
DW2_UnitHeader *hdr = &unit_headers[unit_idx];
DW2_TagParseCtx *ctx = &unit_tag_parse_ctxs[unit_idx];
DW2_ParseCtx *ctx = &unit_parse_ctxs[unit_idx];
ctx->raw = raw;
ctx->version = hdr->version;
ctx->format = hdr->format;
ctx->addr_size = hdr->addr_size;
ctx->abbrev_data = raw->sec[DW_Section_Abbrev].data;
ctx->abbrev_map = abbrev_map_from_unit_idx_table[unit_idx];
}
}
@@ -293,7 +293,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params)
Rng1U64 range = lane_range(unit_count);
for EachInRange(unit_idx, range)
{
dw2_read_tag(scratch.arena, &unit_tag_parse_ctxs[unit_idx], raw->sec[DW_Section_Info].data, unit_info_tag_ranges[unit_idx].min, &unit_root_tags[unit_idx]);
dw2_read_tag(scratch.arena, &unit_parse_ctxs[unit_idx], raw->sec[DW_Section_Info].data, unit_info_tag_ranges[unit_idx].min, &unit_root_tags[unit_idx]);
}
}
lane_sync();