Skip to content

Commit 24efb57

Browse files
factored out inline site decoder into stand alone helper so it can be
reused in the converter
1 parent 3cec629 commit 24efb57

File tree

4 files changed

+351
-464
lines changed

4 files changed

+351
-464
lines changed

src/codeview/codeview_parse.c

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,201 @@ cv_inline_annot_signed_from_unsigned_operand(U32 value)
257257
return result;
258258
}
259259

260+
internal CV_C13InlineSiteDecoder
261+
cv_c13_inline_site_decoder_init(U32 file_off, U32 first_source_ln, U32 parent_voff)
262+
{
263+
CV_C13InlineSiteDecoder decoder = {0};
264+
decoder.parent_voff = parent_voff;
265+
decoder.file_off = file_off;
266+
decoder.ln = (S32)first_source_ln;
267+
decoder.cn = 1;
268+
decoder.ln_changed = 1;
269+
return decoder;
270+
}
271+
272+
internal CV_C13InlineSiteDecoderStep
273+
cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary_annots)
274+
{
275+
CV_C13InlineSiteDecoderStep result = {0};
276+
277+
for (; decoder->cursor < binary_annots.size && result.flags == 0; ) {
278+
U32 op = CV_InlineBinaryAnnotation_Null;
279+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &op);
280+
281+
switch (op) {
282+
case CV_InlineBinaryAnnotation_Null: {
283+
decoder->cursor = binary_annots.size;
284+
// this is last run, append range with left over code bytes
285+
decoder->code_length = decoder->code_offset - decoder->code_offset_lo;
286+
decoder->code_length_changed = 1;
287+
} break;
288+
case CV_InlineBinaryAnnotation_CodeOffset: {
289+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_offset);
290+
decoder->code_offset_changed = 1;
291+
} break;
292+
case CV_InlineBinaryAnnotation_ChangeCodeOffsetBase: {
293+
AssertAlways(!"TODO: test case");
294+
// U32 delta = 0;
295+
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta);
296+
// decoder->code_offset_base = decoder->code_offset;
297+
// decoder->code_offset_end = decoder->code_offset + delta;
298+
// decoder->code_offset += delta;
299+
} break;
300+
case CV_InlineBinaryAnnotation_ChangeCodeOffset: {
301+
U32 delta = 0;
302+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &delta);
303+
304+
decoder->code_offset += delta;
305+
306+
if (!decoder->code_offset_lo_changed) {
307+
decoder->code_offset_lo = decoder->code_offset;
308+
decoder->code_offset_lo_changed = 1;
309+
}
310+
decoder->code_offset_changed = 1;
311+
} break;
312+
case CV_InlineBinaryAnnotation_ChangeCodeLength: {
313+
decoder->code_length = 0;
314+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length);
315+
decoder->code_length_changed = 1;
316+
} break;
317+
case CV_InlineBinaryAnnotation_ChangeFile: {
318+
U32 old_file_off = decoder->file_off;
319+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->file_off);
320+
decoder->file_off_changed = old_file_off != decoder->file_off;
321+
// Compiler isn't obligated to terminate code sequence before chaning files,
322+
// so we have to always force emit code range on file change.
323+
decoder->code_length_changed = decoder->file_off_changed;
324+
} break;
325+
case CV_InlineBinaryAnnotation_ChangeLineOffset: {
326+
S32 delta = 0;
327+
decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta);
328+
329+
decoder->ln += delta;
330+
decoder->ln_changed = 1;
331+
} break;
332+
case CV_InlineBinaryAnnotation_ChangeLineEndDelta: {
333+
AssertAlways(!"TODO: test case");
334+
// S32 end_delta = 1;
335+
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta);
336+
// decoder->ln += end_delta;
337+
} break;
338+
case CV_InlineBinaryAnnotation_ChangeRangeKind: {
339+
AssertAlways(!"TODO: test case");
340+
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &range_kind);
341+
} break;
342+
case CV_InlineBinaryAnnotation_ChangeColumnStart: {
343+
AssertAlways(!"TODO: test case");
344+
// S32 delta;
345+
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &delta);
346+
// decoder->cn += delta;
347+
} break;
348+
case CV_InlineBinaryAnnotation_ChangeColumnEndDelta: {
349+
AssertAlways(!"TODO: test case");
350+
// S32 end_delta;
351+
// decoder->cursor += cv_decode_inline_annot_s32(binary_annots, decoder->cursor, &end_delta);
352+
// decoder->cn += end_delta;
353+
} break;
354+
case CV_InlineBinaryAnnotation_ChangeCodeOffsetAndLineOffset: {
355+
U32 code_offset_and_line_offset = 0;
356+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &code_offset_and_line_offset);
357+
358+
S32 line_delta = cv_inline_annot_signed_from_unsigned_operand(code_offset_and_line_offset >> 4);
359+
U32 code_delta = (code_offset_and_line_offset & 0xf);
360+
361+
decoder->code_offset += code_delta;
362+
decoder->ln += line_delta;
363+
364+
if (!decoder->code_offset_lo_changed) {
365+
decoder->code_offset_lo = decoder->code_offset;
366+
decoder->code_offset_lo_changed = 1;
367+
}
368+
369+
decoder->code_offset_changed = 1;
370+
decoder->ln_changed = 1;
371+
} break;
372+
case CV_InlineBinaryAnnotation_ChangeCodeLengthAndCodeOffset: {
373+
U32 offset_delta = 0;
374+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &decoder->code_length);
375+
decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &offset_delta);
376+
377+
decoder->code_offset += offset_delta;
378+
379+
if (!decoder->code_offset_lo_changed) {
380+
decoder->code_offset_lo = decoder->code_offset;
381+
decoder->code_offset_lo_changed = 1;
382+
}
383+
384+
decoder->code_offset_changed = 1;
385+
decoder->code_length_changed = 1;
386+
} break;
387+
case CV_InlineBinaryAnnotation_ChangeColumnEnd: {
388+
AssertAlways(!"TODO: test case");
389+
// U32 column_end = 0;
390+
// decoder->cursor += cv_decode_inline_annot_u32(binary_annots, decoder->cursor, &column_end);
391+
} break;
392+
}
393+
394+
U64 line_code_offset = decoder->code_offset;
395+
396+
if (decoder->code_length_changed) {
397+
// compute upper bound of the range
398+
U64 code_offset_hi = decoder->code_offset + decoder->code_length;
399+
400+
// can last code range be extended to cover current sequence too?
401+
if (decoder->last_range.max == decoder->parent_voff + decoder->code_offset_lo) {
402+
decoder->last_range.max = decoder->parent_voff + code_offset_hi;
403+
404+
result.flags |= CV_C13InlineSiteDecoderStepFlag_ExtendLastRange;
405+
result.range = decoder->last_range;
406+
} else {
407+
decoder->last_range = rng_1u64(decoder->parent_voff + decoder->code_offset_lo, decoder->parent_voff + code_offset_hi);
408+
decoder->file_last_range = decoder->last_range;
409+
410+
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitRange;
411+
result.range = decoder->last_range;
412+
}
413+
414+
// update state
415+
decoder->code_offset_lo = code_offset_hi;
416+
decoder->code_offset += decoder->code_length;
417+
decoder->code_offset_lo_changed = 0;
418+
decoder->code_length_changed = 0;
419+
decoder->code_length = 0;
420+
}
421+
422+
if (decoder->file_off_changed || (decoder->file_count == 0)) {
423+
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitFile;
424+
result.file_off = decoder->file_off;
425+
426+
// update state
427+
decoder->file_last_range = decoder->last_range;
428+
decoder->file_off_changed = 0;
429+
decoder->file_count += 1;
430+
decoder->file_line_count = 0;
431+
}
432+
433+
if (decoder->code_offset_changed && decoder->ln_changed) {
434+
if (decoder->file_line_count == 0 || decoder->file_last_ln != decoder->ln) {
435+
result.flags |= CV_C13InlineSiteDecoderStepFlag_EmitLine;
436+
result.ln = decoder->ln;
437+
result.cn = decoder->cn;
438+
result.line_voff = decoder->parent_voff + line_code_offset;
439+
result.line_voff_end = decoder->last_range.max;
440+
441+
// update state
442+
decoder->file_line_count += 1;
443+
decoder->file_last_ln = decoder->ln;
444+
}
445+
446+
// update state
447+
decoder->code_offset_changed = 0;
448+
decoder->ln_changed = 0;
449+
}
450+
}
451+
452+
return result;
453+
}
454+
260455
//- Symbol/Leaf Helpers
261456

262457
internal B32

src/codeview/codeview_parse.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,51 @@ struct CV_LeafParsed
9595
////////////////////////////////
9696
//~ CodeView C13 Info Parser Types
9797

98+
typedef struct CV_C13InlineSiteDecoder CV_C13InlineSiteDecoder;
99+
struct CV_C13InlineSiteDecoder
100+
{
101+
U64 cursor;
102+
U64 parent_voff;
103+
CV_InlineRangeKind range_kind;
104+
U32 code_length;
105+
U32 code_offset;
106+
U32 file_off;
107+
S32 ln;
108+
S32 cn;
109+
U64 code_offset_lo;
110+
B32 code_offset_changed;
111+
B32 code_offset_lo_changed;
112+
B32 code_length_changed;
113+
B32 ln_changed;
114+
B32 file_off_changed;
115+
Rng1U64 last_range;
116+
U32 file_count;
117+
Rng1U64 file_last_range;
118+
U64 file_line_count;
119+
U64 file_last_ln;
120+
};
121+
122+
typedef U32 CV_C13InlineSiteDecoderStepFlags;
123+
enum
124+
{
125+
CV_C13InlineSiteDecoderStepFlag_EmitRange = (1 << 0),
126+
CV_C13InlineSiteDecoderStepFlag_ExtendLastRange = (1 << 1),
127+
CV_C13InlineSiteDecoderStepFlag_EmitFile = (1 << 2),
128+
CV_C13InlineSiteDecoderStepFlag_EmitLine = (1 << 3),
129+
};
130+
131+
typedef struct CV_C13InlineSiteDecoderStep CV_C13InlineSiteDecoderStep;
132+
struct CV_C13InlineSiteDecoderStep
133+
{
134+
CV_C13InlineSiteDecoderStepFlags flags;
135+
Rng1U64 range;
136+
U64 line_voff;
137+
U64 line_voff_end;
138+
U64 ln;
139+
U64 cn;
140+
U32 file_off;
141+
};
142+
98143
typedef struct CV_C13LinesParsed CV_C13LinesParsed;
99144
struct CV_C13LinesParsed
100145
{
@@ -213,6 +258,9 @@ internal U64 cv_decode_inline_annot_u32(String8 data, U64 offset, U32 *out_value
213258
internal U64 cv_decode_inline_annot_s32(String8 data, U64 offset, S32 *out_value);
214259
internal S32 cv_inline_annot_signed_from_unsigned_operand(U32 value);
215260

261+
internal CV_C13InlineSiteDecoder cv_c13_inline_site_decoder_init(U32 file_off, U32 first_source_ln, U32 parent_voff);
262+
internal CV_C13InlineSiteDecoderStep cv_c13_inline_site_decoder_step(CV_C13InlineSiteDecoder *decoder, String8 binary_annots);
263+
216264
//- Symbol/Leaf Helpers
217265

218266
internal B32 cv_is_udt_name_anon(String8 name);

0 commit comments

Comments
 (0)