mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-14 16:12:24 -07:00
factored out inline site decoder into stand alone helper so it can be
reused in the converter
This commit is contained in:
@@ -257,6 +257,201 @@ cv_inline_annot_signed_from_unsigned_operand(U32 value)
|
||||
return result;
|
||||
}
|
||||
|
||||
internal CV_C13InlineSiteDecoder
|
||||
cv_c13_inline_site_decoder_init(U32 file_off, U32 first_source_ln, U32 parent_voff)
|
||||
{
|
||||
CV_C13InlineSiteDecoder decoder = {0};
|
||||
decoder.parent_voff = parent_voff;
|
||||
decoder.file_off = file_off;
|
||||
decoder.ln = (S32)first_source_ln;
|
||||
decoder.cn = 1;
|
||||
decoder.ln_changed = 1;
|
||||
return decoder;
|
||||
}
|
||||
|
||||
internal CV_C13InlineSiteDecoderStep
|
||||
cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary_annots)
|
||||
{
|
||||
CV_C13InlineSiteDecoderStep result = {0};
|
||||
|
||||
for (; decoder->cursor < binary_annots.size && result.flags == 0; ) {
|
||||
U32 op = CV_InlineBinaryAnnotation_Null;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &op);
|
||||
|
||||
switch (op) {
|
||||
case CV_InlineBinaryAnnotation_Null: {
|
||||
decoder->cursor = binary_annots.size;
|
||||
// this is last run, append range with left over code bytes
|
||||
decoder->code_length = decoder->code_offset - decoder->code_offset_lo;
|
||||
decoder->code_length_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_CodeOffset: {
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_offset);
|
||||
decoder->code_offset_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// U32 delta = 0;
|
||||
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta);
|
||||
// decoder->code_offset_base = decoder->code_offset;
|
||||
// decoder->code_offset_end = decoder->code_offset + delta;
|
||||
// decoder->code_offset += delta;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffset: {
|
||||
U32 delta = 0;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta);
|
||||
|
||||
decoder->code_offset += delta;
|
||||
|
||||
if (!decoder->code_offset_lo_changed) {
|
||||
decoder->code_offset_lo = decoder->code_offset;
|
||||
decoder->code_offset_lo_changed = 1;
|
||||
}
|
||||
decoder->code_offset_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLength: {
|
||||
decoder->code_length = 0;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length);
|
||||
decoder->code_length_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeFile: {
|
||||
U32 old_file_off = decoder->file_off;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->file_off);
|
||||
decoder->file_off_changed = old_file_off != decoder->file_off;
|
||||
// Compiler isn't obligated to terminate code sequence before chaning files,
|
||||
// so we have to always force emit code range on file change.
|
||||
decoder->code_length_changed = decoder->file_off_changed;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineOffset: {
|
||||
S32 delta = 0;
|
||||
decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta);
|
||||
|
||||
decoder->ln += delta;
|
||||
decoder->ln_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineEndDelta: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 end_delta = 1;
|
||||
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta);
|
||||
// decoder->ln += end_delta;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeRangeKind: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &range_kind);
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnStart: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 delta;
|
||||
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta);
|
||||
// decoder->cn += delta;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEndDelta: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 end_delta;
|
||||
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta);
|
||||
// decoder->cn += end_delta;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: {
|
||||
U32 code_offset_and_line_offset = 0;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &code_offset_and_line_offset);
|
||||
|
||||
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
|
||||
U32 code_delta = (code_offset_and_line_offset & 0xf);
|
||||
|
||||
decoder->code_offset += code_delta;
|
||||
decoder->ln += line_delta;
|
||||
|
||||
if (!decoder->code_offset_lo_changed) {
|
||||
decoder->code_offset_lo = decoder->code_offset;
|
||||
decoder->code_offset_lo_changed = 1;
|
||||
}
|
||||
|
||||
decoder->code_offset_changed = 1;
|
||||
decoder->ln_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: {
|
||||
U32 offset_delta = 0;
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length);
|
||||
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &offset_delta);
|
||||
|
||||
decoder->code_offset += offset_delta;
|
||||
|
||||
if (!decoder->code_offset_lo_changed) {
|
||||
decoder->code_offset_lo = decoder->code_offset;
|
||||
decoder->code_offset_lo_changed = 1;
|
||||
}
|
||||
|
||||
decoder->code_offset_changed = 1;
|
||||
decoder->code_length_changed = 1;
|
||||
} break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEnd: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// U32 column_end = 0;
|
||||
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &column_end);
|
||||
} break;
|
||||
}
|
||||
|
||||
U64 line_code_offset = decoder->code_offset;
|
||||
|
||||
if (decoder->code_length_changed) {
|
||||
// compute upper bound of the range
|
||||
U64 code_offset_hi = decoder->code_offset + decoder->code_length;
|
||||
|
||||
// can last code range be extended to cover current sequence too?
|
||||
if (decoder->last_range.max == decoder->parent_voff + decoder->code_offset_lo) {
|
||||
decoder->last_range.max = decoder->parent_voff + code_offset_hi;
|
||||
|
||||
result.flags |= CV_C13InlineSiteDecoderStepFlag_ExtendLastRange;
|
||||
result.range = decoder->last_range;
|
||||
} else {
|
||||
decoder->last_range = rng_1u64(decoder->parent_voff + decoder->code_offset_lo, decoder->parent_voff + code_offset_hi);
|
||||
decoder->file_last_range = decoder->last_range;
|
||||
|
||||
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitRange;
|
||||
result.range = decoder->last_range;
|
||||
}
|
||||
|
||||
// update state
|
||||
decoder->code_offset_lo = code_offset_hi;
|
||||
decoder->code_offset += decoder->code_length;
|
||||
decoder->code_offset_lo_changed = 0;
|
||||
decoder->code_length_changed = 0;
|
||||
decoder->code_length = 0;
|
||||
}
|
||||
|
||||
if (decoder->file_off_changed || (decoder->file_count == 0)) {
|
||||
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitFile;
|
||||
result.file_off = decoder->file_off;
|
||||
|
||||
// update state
|
||||
decoder->file_last_range = decoder->last_range;
|
||||
decoder->file_off_changed = 0;
|
||||
decoder->file_count += 1;
|
||||
decoder->file_line_count = 0;
|
||||
}
|
||||
|
||||
if (decoder->code_offset_changed && decoder->ln_changed) {
|
||||
if (decoder->file_line_count == 0 || decoder->file_last_ln != decoder->ln) {
|
||||
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitLine;
|
||||
result.ln = decoder->ln;
|
||||
result.cn = decoder->cn;
|
||||
result.line_voff = decoder->parent_voff + line_code_offset;
|
||||
result.line_voff_end = decoder->last_range.max;
|
||||
|
||||
// update state
|
||||
decoder->file_line_count += 1;
|
||||
decoder->file_last_ln = decoder->ln;
|
||||
}
|
||||
|
||||
// update state
|
||||
decoder->code_offset_changed = 0;
|
||||
decoder->ln_changed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//- Symbol/Leaf Helpers
|
||||
|
||||
internal B32
|
||||
|
||||
@@ -95,6 +95,51 @@ struct CV_LeafParsed
|
||||
////////////////////////////////
|
||||
//~ CodeView C13 Info Parser Types
|
||||
|
||||
typedef struct CV_C13InlineSiteDecoder CV_C13InlineSiteDecoder;
|
||||
struct CV_C13InlineSiteDecoder
|
||||
{
|
||||
U64 cursor;
|
||||
U64 parent_voff;
|
||||
CV_InlineRangeKind range_kind;
|
||||
U32 code_length;
|
||||
U32 code_offset;
|
||||
U32 file_off;
|
||||
S32 ln;
|
||||
S32 cn;
|
||||
U64 code_offset_lo;
|
||||
B32 code_offset_changed;
|
||||
B32 code_offset_lo_changed;
|
||||
B32 code_length_changed;
|
||||
B32 ln_changed;
|
||||
B32 file_off_changed;
|
||||
Rng1U64 last_range;
|
||||
U32 file_count;
|
||||
Rng1U64 file_last_range;
|
||||
U64 file_line_count;
|
||||
U64 file_last_ln;
|
||||
};
|
||||
|
||||
typedef U32 CV_C13InlineSiteDecoderStepFlags;
|
||||
enum
|
||||
{
|
||||
CV_C13InlineSiteDecoderStepFlag_EmitRange = (1 << 0),
|
||||
CV_C13InlineSiteDecoderStepFlag_ExtendLastRange = (1 << 1),
|
||||
CV_C13InlineSiteDecoderStepFlag_EmitFile = (1 << 2),
|
||||
CV_C13InlineSiteDecoderStepFlag_EmitLine = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct CV_C13InlineSiteDecoderStep CV_C13InlineSiteDecoderStep;
|
||||
struct CV_C13InlineSiteDecoderStep
|
||||
{
|
||||
CV_C13InlineSiteDecoderStepFlags flags;
|
||||
Rng1U64 range;
|
||||
U64 line_voff;
|
||||
U64 line_voff_end;
|
||||
U64 ln;
|
||||
U64 cn;
|
||||
U32 file_off;
|
||||
};
|
||||
|
||||
typedef struct CV_C13LinesParsed CV_C13LinesParsed;
|
||||
struct CV_C13LinesParsed
|
||||
{
|
||||
@@ -213,6 +258,9 @@ internal U64 cv_decode_inline_annot_u32(String8 data, U64 offset, U32 *out_value
|
||||
internal U64 cv_decode_inline_annot_s32(String8 data, U64 offset, S32 *out_value);
|
||||
internal S32 cv_inline_annot_signed_from_unsigned_operand(U32 value);
|
||||
|
||||
internal CV_C13InlineSiteDecoder cv_c13_inline_site_decoder_init(U32 file_off, U32 first_source_ln, U32 parent_voff);
|
||||
internal CV_C13InlineSiteDecoderStep cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary_annots);
|
||||
|
||||
//- Symbol/Leaf Helpers
|
||||
|
||||
internal B32 cv_is_udt_name_anon(String8 name);
|
||||
|
||||
@@ -1985,198 +1985,33 @@ cv_c13_parse_inline_binary_annots(Arena *arena,
|
||||
struct SourceFile *file_last = 0;
|
||||
U64 file_count = 0;
|
||||
|
||||
CV_InlineRangeKind range_kind = 0; (void)range_kind;
|
||||
U32 code_length = 0;
|
||||
U32 code_offset = 0;
|
||||
U32 file_off = inlinee_parsed->file_off;
|
||||
S32 ln = (S32)inlinee_parsed->first_source_ln;
|
||||
S32 cn = 1;
|
||||
U64 code_offset_lo = 0;
|
||||
B32 code_offset_changed = 0;
|
||||
B32 code_offset_lo_changed = 0;
|
||||
B32 code_length_changed = 0;
|
||||
B32 ln_changed = 1;
|
||||
B32 file_off_changed = 0;
|
||||
|
||||
for (U64 cursor = 0, keep_running = 1; cursor < binary_annots.size && keep_running; ) {
|
||||
U32 op = CV_InlineBinaryAnnotation_Null;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &op);
|
||||
|
||||
switch (op) {
|
||||
case CV_InlineBinaryAnnotation_Null: {
|
||||
keep_running = 0;
|
||||
|
||||
// this is last run, append range with left over code bytes
|
||||
code_length = code_offset - code_offset_lo;
|
||||
code_length_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_CodeOffset: {
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset);
|
||||
code_offset_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// U32 delta = 0;
|
||||
// cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
|
||||
// code_offset_base = code_offset;
|
||||
// code_offset_end = code_offset + delta;
|
||||
// code_offset += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffset: {
|
||||
U32 delta = 0;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &delta);
|
||||
|
||||
code_offset += delta;
|
||||
|
||||
if (!code_offset_lo_changed) {
|
||||
code_offset_lo = code_offset;
|
||||
code_offset_lo_changed = 1;
|
||||
}
|
||||
code_offset_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLength: {
|
||||
code_length = 0;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_length);
|
||||
code_length_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeFile: {
|
||||
U32 old_file_off = file_off;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &file_off);
|
||||
file_off_changed = old_file_off != file_off;
|
||||
// Compiler isn't obligated to terminate code sequence before chaning files,
|
||||
// so we have to always force emit code range on file change.
|
||||
code_length_changed = file_off_changed;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineOffset: {
|
||||
S32 delta = 0;
|
||||
cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
|
||||
|
||||
ln += delta;
|
||||
ln_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineEndDelta: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 end_delta = 1;
|
||||
// cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &end_delta);
|
||||
// ln += end_delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeRangeKind: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &range_kind);
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnStart: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 delta;
|
||||
// cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &delta);
|
||||
// cn += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEndDelta: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// S32 end_delta;
|
||||
// cursor += cv_decode_inline_annot_s32(binary_annots, cursor, &end_delta);
|
||||
// cn += end_delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: {
|
||||
U32 code_offset_and_line_offset = 0;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_offset_and_line_offset);
|
||||
|
||||
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
|
||||
U32 code_delta = (code_offset_and_line_offset & 0xf);
|
||||
|
||||
code_offset += code_delta;
|
||||
ln += line_delta;
|
||||
|
||||
if (!code_offset_lo_changed) {
|
||||
code_offset_lo = code_offset;
|
||||
code_offset_lo_changed = 1;
|
||||
}
|
||||
|
||||
code_offset_changed = 1;
|
||||
ln_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: {
|
||||
U32 offset_delta = 0;
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &code_length);
|
||||
cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &offset_delta);
|
||||
|
||||
code_offset += offset_delta;
|
||||
|
||||
if (!code_offset_lo_changed) {
|
||||
code_offset_lo = code_offset;
|
||||
code_offset_lo_changed = 1;
|
||||
}
|
||||
|
||||
code_offset_changed = 1;
|
||||
code_length_changed = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEnd: {
|
||||
AssertAlways(!"TODO: test case");
|
||||
// U32 column_end = 0;
|
||||
// cursor += cv_decode_inline_annot_u32(binary_annots, cursor, &column_end);
|
||||
}break;
|
||||
CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_parsed->file_off, inlinee_parsed->first_source_ln, parent_voff);
|
||||
for (;;) {
|
||||
CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots);
|
||||
if (step.flags == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
U64 line_code_offset = code_offset;
|
||||
|
||||
if (code_length_changed) {
|
||||
// compute upper bound of the range
|
||||
U64 code_offset_hi = code_offset + code_length;
|
||||
|
||||
// can last code range be extended to cover current sequence too?
|
||||
if (code_ranges.last != 0 && code_ranges.last->v.max == parent_voff + code_offset_lo) {
|
||||
code_ranges.last->v.max = parent_voff + code_offset_hi;
|
||||
} else {
|
||||
// append range
|
||||
rng1u64_list_push(arena, &code_ranges, rng_1u64(parent_voff + code_offset_lo, parent_voff + code_offset_hi));
|
||||
|
||||
// update last code range in file
|
||||
if (file_last) {
|
||||
file_last->last_code_range = code_ranges.last->v;
|
||||
}
|
||||
}
|
||||
|
||||
// update low offset for next range
|
||||
code_offset_lo = code_offset_hi;
|
||||
|
||||
// advance code offset
|
||||
code_offset += code_length;
|
||||
|
||||
// reset state
|
||||
code_offset_lo_changed = 0;
|
||||
code_length_changed = 0;
|
||||
code_length = 0;
|
||||
if (step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange) {
|
||||
rng1u64_list_push(scratch.arena, &code_ranges, step.range);
|
||||
}
|
||||
|
||||
if (file_off_changed || (file_first == 0)) {
|
||||
// append file
|
||||
if (step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange) {
|
||||
if (code_ranges.last) {
|
||||
code_ranges.last->v = step.range;
|
||||
}
|
||||
}
|
||||
if (step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile) {
|
||||
struct SourceFile *file = push_array(scratch.arena, struct SourceFile, 1);
|
||||
file->checksum_off = file_off;
|
||||
file->checksum_off = step.file_off;
|
||||
SLLQueuePush(file_first, file_last, file);
|
||||
++file_count;
|
||||
|
||||
// update last code range in file
|
||||
if (code_ranges.last) {
|
||||
file->last_code_range = code_ranges.last->v;
|
||||
}
|
||||
|
||||
// reset state
|
||||
file_off_changed = 0;
|
||||
}
|
||||
|
||||
if (code_offset_changed && ln_changed) {
|
||||
if (file_last->line_last == 0 || file_last->line_last->ln != (U64)ln) {
|
||||
// append line
|
||||
struct SourceLine *line = push_array(scratch.arena, struct SourceLine, 1);
|
||||
line->voff = parent_voff + line_code_offset;
|
||||
line->ln = (U64)ln;
|
||||
line->cn = (U64)cn;
|
||||
SLLQueuePush(file_last->line_first, file_last->line_last, line);
|
||||
++file_last->line_count;
|
||||
}
|
||||
|
||||
// reset state
|
||||
code_offset_changed = 0;
|
||||
ln_changed = 0;
|
||||
if (step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine) {
|
||||
struct SourceLine *line = push_array(scratch.arena, struct SourceLine, 1);
|
||||
line->voff = step.line_voff;
|
||||
line->ln = step.ln;
|
||||
line->cn = step.cn;
|
||||
SLLQueuePush(file_last->line_first, file_last->line_last, line);
|
||||
++file_last->line_count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2209,9 +2044,9 @@ cv_c13_parse_inline_binary_annots(Arena *arena,
|
||||
|
||||
// fill out result
|
||||
CV_InlineBinaryAnnotsParsed result = {0};
|
||||
result.lines_count = file_count;
|
||||
result.lines = lines;
|
||||
result.code_ranges = code_ranges;
|
||||
result.lines_count = file_count;
|
||||
result.lines = lines;
|
||||
result.code_ranges = code_ranges;
|
||||
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
|
||||
+85
-276
@@ -787,203 +787,58 @@ ASYNC_WORK_DEF(p2r_units_convert_work)
|
||||
}
|
||||
|
||||
// rjf: build line table, fill with parsed binary annotations
|
||||
RDIM_LineTable *line_table = 0;
|
||||
|
||||
if(inlinee_lines_parsed != 0)
|
||||
{
|
||||
// rjf: state machine registers
|
||||
CV_InlineRangeKind range_kind = 0;
|
||||
U32 code_length = 0;
|
||||
U32 code_offset = 0;
|
||||
String8 file_name = inlinee_lines_parsed->file_name;
|
||||
String8 last_file_name = {0};
|
||||
S32 line = (S32)inlinee_lines_parsed->first_source_ln;
|
||||
S32 column = 1;
|
||||
S32 last_column = column;
|
||||
|
||||
// rjf: grab checksums sub-section
|
||||
CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section;
|
||||
|
||||
// rjf: gathered lines
|
||||
typedef struct LineChunk LineChunk;
|
||||
struct LineChunk
|
||||
{
|
||||
LineChunk *next;
|
||||
U64 cap;
|
||||
U64 count;
|
||||
U64 *voffs; // [line_count + 1] (sorted)
|
||||
U32 *line_nums; // [line_count]
|
||||
U16 *col_nums; // [2*line_count]
|
||||
U64 cap;
|
||||
U64 count;
|
||||
U64 *voffs; // [line_count + 1] (sorted)
|
||||
U32 *line_nums; // [line_count]
|
||||
U16 *col_nums; // [2*line_count]
|
||||
};
|
||||
LineChunk *first_line_chunk = 0;
|
||||
LineChunk *last_line_chunk = 0;
|
||||
U64 total_line_chunk_line_count = 0;
|
||||
|
||||
// rjf: grab checksums sub-section
|
||||
CV_C13SubSectionNode *file_chksms = unit_c13->file_chksms_sub_section;
|
||||
|
||||
// rjf: decode loop
|
||||
B32 line_num_emitted = 0;
|
||||
B32 code_off_emitted = 0;
|
||||
B32 code_len_emitted = 0;
|
||||
U64 read_off = 0;
|
||||
U64 read_off_opl = binary_annots.size;
|
||||
for(B32 good = 1; read_off < read_off_opl && good;)
|
||||
LineChunk *first_line_chunk = 0;
|
||||
LineChunk *last_line_chunk = 0;
|
||||
U64 total_line_chunk_line_count = 0;
|
||||
U32 last_file_off = max_U32;
|
||||
U32 curr_file_off = max_U32;
|
||||
RDIM_LineTable* line_table = 0;
|
||||
|
||||
CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(inlinee_lines_parsed->file_off, inlinee_lines_parsed->first_source_ln, base_voff);
|
||||
for(;;)
|
||||
{
|
||||
// rjf: decode next annotation op
|
||||
U32 op = CV_InlineBinaryAnnotation_Null;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &op);
|
||||
|
||||
// rjf: apply op
|
||||
switch(op)
|
||||
CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots);
|
||||
|
||||
if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitFile)
|
||||
{
|
||||
default:{good = 0;}break;
|
||||
case CV_InlineBinaryAnnotation_Null:
|
||||
{
|
||||
good = 0;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_CodeOffset:
|
||||
{
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_offset);
|
||||
code_off_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase:
|
||||
{
|
||||
good = 0;
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// U32 delta = 0;
|
||||
// read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &delta);
|
||||
// code_offset_base = code_offset;
|
||||
// code_offset_end = code_offset + delta;
|
||||
// code_offset += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffset:
|
||||
{
|
||||
U32 delta = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &delta);
|
||||
code_offset += delta;
|
||||
code_off_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLength:
|
||||
{
|
||||
code_length = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length);
|
||||
code_len_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeFile:
|
||||
{
|
||||
U32 new_file_off = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &new_file_off);
|
||||
String8 new_file_name = {0};
|
||||
if(new_file_off + sizeof(CV_C13Checksum) <= file_chksms->size)
|
||||
{
|
||||
CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + new_file_off);
|
||||
U32 name_off = checksum->name_off;
|
||||
new_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off);
|
||||
}
|
||||
file_name = new_file_name;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineOffset:
|
||||
{
|
||||
S32 delta = 0;
|
||||
read_off += cv_decode_inline_annot_s32(binary_annots, read_off, &delta);
|
||||
line += delta;
|
||||
line_num_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeLineEndDelta:
|
||||
{
|
||||
good = 0;
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// S32 end_delta = 1;
|
||||
// read_off += cv_decode_inline_annot_s32(binary_annots, read_off, &end_delta);
|
||||
// line += end_delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeRangeKind:
|
||||
{
|
||||
good = 0;
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &range_kind);
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnStart:
|
||||
{
|
||||
good = 0;
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// S32 delta = 0;
|
||||
// read_off += cv_decode_inline_annot_s32(binary_annots, read_off, &delta);
|
||||
// column += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEndDelta:
|
||||
{
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// S32 end_delta = 0;
|
||||
// read_off += cv_decode_inline_annot_s32(binary_annots, read_off, &end_delta);
|
||||
// column += end_delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset:
|
||||
{
|
||||
U32 code_offset_and_line_offset = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_offset_and_line_offset);
|
||||
U32 code_delta = (code_offset_and_line_offset & 0xf);
|
||||
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
|
||||
code_offset += code_delta;
|
||||
line += line_delta;
|
||||
code_off_emitted = 1;
|
||||
line_num_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset:
|
||||
{
|
||||
U32 offset_delta = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length);
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &offset_delta);
|
||||
code_offset += offset_delta;
|
||||
code_len_emitted = 1;
|
||||
code_off_emitted = 1;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeColumnEnd:
|
||||
{
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// U32 column_end = 0;
|
||||
// read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &column_end);
|
||||
}break;
|
||||
last_file_off = curr_file_off;
|
||||
curr_file_off = step.file_off;
|
||||
}
|
||||
|
||||
// rjf: gather new lines
|
||||
if(!good || (line_num_emitted && code_off_emitted && code_len_emitted))
|
||||
if(step.flags == 0 && total_line_chunk_line_count > 0)
|
||||
{
|
||||
LineChunk *chunk = last_line_chunk;
|
||||
if(chunk == 0 || chunk->count+1 >= chunk->cap)
|
||||
last_file_off = curr_file_off;
|
||||
curr_file_off = max_U32;
|
||||
}
|
||||
if((last_file_off != max_U32 && last_file_off != curr_file_off))
|
||||
{
|
||||
String8 seq_file_name = {0};
|
||||
|
||||
if(last_file_off + sizeof(CV_C13Checksum) <= file_chksms->size)
|
||||
{
|
||||
chunk = push_array(scratch.arena, LineChunk, 1);
|
||||
SLLQueuePush(first_line_chunk, last_line_chunk, chunk);
|
||||
chunk->cap = 256;
|
||||
chunk->voffs = push_array_no_zero(scratch.arena, U64, chunk->cap);
|
||||
chunk->line_nums = push_array_no_zero(scratch.arena, U32, chunk->cap);
|
||||
CV_C13Checksum *checksum = (CV_C13Checksum*)(unit_c13->data.str + file_chksms->off + last_file_off);
|
||||
U32 name_off = checksum->name_off;
|
||||
seq_file_name = pdb_strtbl_string_from_off(in->pdb_strtbl, name_off);
|
||||
}
|
||||
chunk->voffs[chunk->count] = base_voff + code_offset;
|
||||
chunk->voffs[chunk->count+1] = base_voff + code_offset + code_length;
|
||||
chunk->line_nums[chunk->count] = (U32)line;
|
||||
chunk->count += 1;
|
||||
total_line_chunk_line_count += 1;
|
||||
line_num_emitted = 0;
|
||||
code_off_emitted = 0;
|
||||
code_len_emitted = 0;
|
||||
}
|
||||
|
||||
// rjf: advance code offset by the code length
|
||||
{
|
||||
code_offset += code_length;
|
||||
code_length = 0;
|
||||
}
|
||||
|
||||
// rjf: push line sequence to line table & source file
|
||||
if(!good || (op == CV_InlineBinaryAnnotation_ChangeFile && !str8_match(last_file_name, file_name, 0)))
|
||||
{
|
||||
String8 seq_file_name = last_file_name; // NOTE(rjf): `file_name` is possibly changed to the next sequence, so use previous
|
||||
|
||||
// rjf: file name -> normalized file path
|
||||
String8 file_path = seq_file_name;
|
||||
String8 file_path = seq_file_name;
|
||||
String8 file_path_normalized = lower_from_str8(scratch.arena, str8_skip_chop_whitespace(file_path));
|
||||
for(U64 idx = 0; idx < file_path_normalized.size; idx += 1)
|
||||
{
|
||||
@@ -994,9 +849,9 @@ ASYNC_WORK_DEF(p2r_units_convert_work)
|
||||
}
|
||||
|
||||
// rjf: normalized file path -> source file node
|
||||
U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size);
|
||||
U64 src_file_slot = file_path_normalized_hash%src_file_map.slots_count;
|
||||
P2R_SrcFileNode *src_file_node = 0;
|
||||
U64 file_path_normalized_hash = rdi_hash(file_path_normalized.str, file_path_normalized.size);
|
||||
U64 src_file_slot = file_path_normalized_hash%src_file_map.slots_count;
|
||||
P2R_SrcFileNode *src_file_node = 0;
|
||||
for(P2R_SrcFileNode *n = src_file_map.slots[src_file_slot]; n != 0; n = n->next)
|
||||
{
|
||||
if(str8_match(n->src_file->normal_full_path, file_path_normalized, 0))
|
||||
@@ -1009,23 +864,22 @@ ASYNC_WORK_DEF(p2r_units_convert_work)
|
||||
{
|
||||
src_file_node = push_array(scratch.arena, P2R_SrcFileNode, 1);
|
||||
SLLStackPush(src_file_map.slots[src_file_slot], src_file_node);
|
||||
src_file_node->src_file = rdim_src_file_chunk_list_push(arena, &out->src_files, 4096);
|
||||
src_file_node->src_file = rdim_src_file_chunk_list_push(arena, &out->src_files, 4096);
|
||||
src_file_node->src_file->normal_full_path = push_str8_copy(arena, file_path_normalized);
|
||||
}
|
||||
|
||||
// rjf: gather all lines
|
||||
RDI_U64 *voffs = push_array_no_zero(arena, RDI_U64, total_line_chunk_line_count+1);
|
||||
RDI_U32 *line_nums = push_array_no_zero(arena, RDI_U32, total_line_chunk_line_count);
|
||||
RDI_U64 line_count = total_line_chunk_line_count;
|
||||
RDI_U64 *voffs = push_array_no_zero(arena, RDI_U64, total_line_chunk_line_count+1);
|
||||
RDI_U32 *line_nums = push_array_no_zero(arena, RDI_U32, total_line_chunk_line_count);
|
||||
RDI_U64 line_count = total_line_chunk_line_count;
|
||||
{
|
||||
U64 dst_idx = 0;
|
||||
for(LineChunk *chunk = first_line_chunk; chunk != 0; chunk = chunk->next)
|
||||
{
|
||||
MemoryCopy(voffs+dst_idx, chunk->voffs, sizeof(U64)*chunk->count);
|
||||
MemoryCopy(voffs+dst_idx, chunk->voffs, sizeof(U64)*(chunk->count+1));
|
||||
MemoryCopy(line_nums+dst_idx, chunk->line_nums, sizeof(U32)*chunk->count);
|
||||
dst_idx += chunk->count;
|
||||
}
|
||||
voffs[dst_idx] = 0xffffffffffffffffull;
|
||||
}
|
||||
|
||||
// rjf: push
|
||||
@@ -1044,9 +898,32 @@ ASYNC_WORK_DEF(p2r_units_convert_work)
|
||||
}
|
||||
|
||||
// rjf: clear line chunks for subsequent sequences
|
||||
first_line_chunk = last_line_chunk = 0;
|
||||
first_line_chunk = last_line_chunk = 0;
|
||||
total_line_chunk_line_count = 0;
|
||||
}
|
||||
|
||||
if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitLine)
|
||||
{
|
||||
LineChunk *chunk = last_line_chunk;
|
||||
if(chunk == 0 || chunk->count+1 >= chunk->cap)
|
||||
{
|
||||
chunk = push_array(scratch.arena, LineChunk, 1);
|
||||
SLLQueuePush(first_line_chunk, last_line_chunk, chunk);
|
||||
chunk->cap = 256;
|
||||
chunk->voffs = push_array_no_zero(scratch.arena, U64, chunk->cap);
|
||||
chunk->line_nums = push_array_no_zero(scratch.arena, U32, chunk->cap);
|
||||
}
|
||||
chunk->voffs[chunk->count] = step.line_voff;
|
||||
chunk->voffs[chunk->count+1] = step.line_voff_end;
|
||||
chunk->line_nums[chunk->count] = step.ln;
|
||||
chunk->count += 1;
|
||||
total_line_chunk_line_count += 1;
|
||||
}
|
||||
|
||||
if(step.flags == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
@@ -2988,98 +2865,30 @@ ASYNC_WORK_DEF(p2r_symbol_stream_convert_work)
|
||||
|
||||
// rjf: parse offset ranges of this inline site - attach to scope
|
||||
{
|
||||
U32 code_length = 0;
|
||||
U32 code_offset = 0;
|
||||
U32 last_code_offset = code_offset;
|
||||
U32 last_code_length = code_length;
|
||||
U64 read_off = 0;
|
||||
U64 read_off_opl = binary_annots.size;
|
||||
for(B32 good = 1; read_off < read_off_opl && good;)
|
||||
CV_C13InlineSiteDecoder decoder = cv_c13_inline_site_decoder_init(0, 0, procedure_base_voff);
|
||||
for(;;)
|
||||
{
|
||||
// rjf: decode next annotation op
|
||||
U32 op = CV_InlineBinaryAnnotation_Null;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &op);
|
||||
|
||||
// rjf: apply op
|
||||
switch(op)
|
||||
CV_C13InlineSiteDecoderStep step = cv_c13_inline_site_decoder_step(&decoder, binary_annots);
|
||||
|
||||
if(step.flags & CV_C13InlineSiteDecoderStepFlag_EmitRange)
|
||||
{
|
||||
default:{good = 1;}break;
|
||||
case CV_InlineBinaryAnnotation_Null:
|
||||
{
|
||||
good = 0;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_CodeOffset:
|
||||
{
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_offset);
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase:
|
||||
{
|
||||
good = 0;
|
||||
// TODO(rjf): currently untested/unknown - first guess below:
|
||||
//
|
||||
// U32 delta = 0;
|
||||
// read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &delta);
|
||||
// code_offset_base = code_offset;
|
||||
// code_offset_end = code_offset + delta;
|
||||
// code_offset += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffset:
|
||||
{
|
||||
U32 delta = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &delta);
|
||||
code_offset += delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLength:
|
||||
{
|
||||
code_length = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length);
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset:
|
||||
{
|
||||
U32 code_offset_and_line_offset = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_offset_and_line_offset);
|
||||
U32 code_delta = (code_offset_and_line_offset & 0xf);
|
||||
code_offset += code_delta;
|
||||
}break;
|
||||
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset:
|
||||
{
|
||||
U32 offset_delta = 0;
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &code_length);
|
||||
read_off += cv_decode_inline_annot_u32(binary_annots, read_off, &offset_delta);
|
||||
code_offset += offset_delta;
|
||||
}break;
|
||||
// rjf: build new range & add to scope
|
||||
RDIM_Rng1U64 voff_range = { step.range.min, step.range.max };
|
||||
rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range);
|
||||
}
|
||||
|
||||
// rjf: gather new ranges
|
||||
if(last_code_length != code_length)
|
||||
|
||||
if(step.flags & CV_C13InlineSiteDecoderStepFlag_ExtendLastRange)
|
||||
{
|
||||
// rjf: convert current state machine state to [first_voff, opl_voff) range
|
||||
RDIM_Rng1U64 voff_range =
|
||||
if(scope->voff_ranges.last != 0)
|
||||
{
|
||||
procedure_base_voff + code_offset,
|
||||
procedure_base_voff + code_offset + code_length,
|
||||
};
|
||||
|
||||
// rjf: attempt to extend last-added range to cover this range, if possible
|
||||
if(scope->voff_ranges.last != 0 && scope->voff_ranges.last->v.max == voff_range.min)
|
||||
{
|
||||
scope->voff_ranges.last->v.max = voff_range.max;
|
||||
scope->voff_ranges.last->v.max = step.range.max;
|
||||
}
|
||||
|
||||
// rjf: cannot add to previous range? -> build new range & add to scope
|
||||
else
|
||||
{
|
||||
rdim_scope_push_voff_range(arena, &sym_scopes, scope, voff_range);
|
||||
}
|
||||
|
||||
// rjf: advance
|
||||
code_offset += code_length;
|
||||
code_length = 0;
|
||||
}
|
||||
|
||||
// rjf: update prev/current states
|
||||
last_code_offset = code_offset;
|
||||
last_code_length = code_length;
|
||||
|
||||
if(step.flags == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
Reference in New Issue
Block a user