mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
test mismatched PCH signatures and presence of .debug$P and .debug$T in
same obj
This commit is contained in:
+23
-23
@@ -280,8 +280,8 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProfBegin("Parse CodeView");
|
ProfBegin("Parse CodeView");
|
||||||
|
CV_DebugT *debug_p_arr = lnk_parse_debug_t_sections(tp, tp_arena, obj_count, obj_arr, debug_p_list_arr);
|
||||||
input.debug_s_arr = lnk_parse_debug_s_sections(tp, tp_arena, obj_count, obj_arr, debug_s_list_arr);
|
input.debug_s_arr = lnk_parse_debug_s_sections(tp, tp_arena, obj_count, obj_arr, debug_s_list_arr);
|
||||||
input.debug_p_arr = lnk_parse_debug_t_sections(tp, tp_arena, obj_count, obj_arr, debug_p_list_arr);
|
|
||||||
input.debug_t_arr = lnk_parse_debug_t_sections(tp, tp_arena, obj_count, obj_arr, debug_t_list_arr);
|
input.debug_t_arr = lnk_parse_debug_t_sections(tp, tp_arena, obj_count, obj_arr, debug_t_list_arr);
|
||||||
input.debug_h_arr = push_array(tp_arena->v[0], CV_DebugH, obj_count); // TODO: collect & parse .debug$H
|
input.debug_h_arr = push_array(tp_arena->v[0], CV_DebugH, obj_count); // TODO: collect & parse .debug$H
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
@@ -324,17 +324,20 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
input.int_obj_indices.v = push_array(tp_arena->v[0], U32, obj_count);
|
input.int_obj_indices.v = push_array(tp_arena->v[0], U32, obj_count);
|
||||||
for EachIndex(obj_idx, obj_count) {
|
for EachIndex(obj_idx, obj_count) {
|
||||||
CV_DebugT *debug_t = &input.debug_t_arr[obj_idx];
|
CV_DebugT *debug_t = &input.debug_t_arr[obj_idx];
|
||||||
CV_DebugT *debug_p = &input.debug_p_arr[obj_idx];
|
CV_DebugT *debug_p = &debug_p_arr[obj_idx];
|
||||||
U32Array *arr_ptr;
|
U32Array *arr_ptr;
|
||||||
|
if (debug_p->count > 0 && debug_t->count == 0) { arr_ptr = &input.debug_p_indices; }
|
||||||
if (debug_t->count && debug_p->count) {
|
|
||||||
lnk_error_obj(LNK_Warning_MultipleDebugTAndDebugP, obj_arr[obj_idx], "multiple sections with debug types detected, obj must have either .debug$T or .debug$P (using .debug$T for type server)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_p->count > 0) { arr_ptr = &input.debug_p_indices; }
|
|
||||||
else if (cv_debug_t_is_type_server_ref(debug_t)) { arr_ptr = &input.ext_obj_indices; }
|
else if (cv_debug_t_is_type_server_ref(debug_t)) { arr_ptr = &input.ext_obj_indices; }
|
||||||
else { arr_ptr = &input.int_obj_indices; }
|
else { arr_ptr = &input.int_obj_indices; }
|
||||||
arr_ptr->v[arr_ptr->count++] = obj_idx;
|
arr_ptr->v[arr_ptr->count++] = obj_idx;
|
||||||
|
|
||||||
|
if (debug_t->count == 0 && debug_p->count > 0) {
|
||||||
|
*debug_t = *debug_p;
|
||||||
|
} else if (debug_t->count && debug_p->count) {
|
||||||
|
lnk_error_obj(LNK_Warning_MultipleDebugTAndDebugP, obj_arr[obj_idx], "multiple sections with debug types detected, obj must have either .debug$T or .debug$P; discarding both sections");
|
||||||
|
MemoryZeroStruct(debug_t);
|
||||||
|
MemoryZeroStruct(debug_p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfScope("Set up type servers")
|
ProfScope("Set up type servers")
|
||||||
@@ -398,7 +401,6 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
input.count += ts_arr.count;
|
input.count += ts_arr.count;
|
||||||
input.obj_arr = push_array(tp_arena->v[0], LNK_Obj *, input.count);
|
input.obj_arr = push_array(tp_arena->v[0], LNK_Obj *, input.count);
|
||||||
input.debug_s_arr = push_array(tp_arena->v[0], CV_DebugS, input.count);
|
input.debug_s_arr = push_array(tp_arena->v[0], CV_DebugS, input.count);
|
||||||
input.debug_p_arr = push_array(tp_arena->v[0], CV_DebugT, input.count);
|
|
||||||
input.debug_t_arr = push_array(tp_arena->v[0], CV_DebugT, input.count);
|
input.debug_t_arr = push_array(tp_arena->v[0], CV_DebugT, input.count);
|
||||||
input.debug_h_arr = push_array(tp_arena->v[0], CV_DebugH, input.count);
|
input.debug_h_arr = push_array(tp_arena->v[0], CV_DebugH, input.count);
|
||||||
input.parsed_symbols = push_array(tp_arena->v[0], CV_SymbolListArray, input.count);
|
input.parsed_symbols = push_array(tp_arena->v[0], CV_SymbolListArray, input.count);
|
||||||
@@ -406,7 +408,6 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
|
|
||||||
MemoryCopyTyped(input.obj_arr, prev.obj_arr, prev.count);
|
MemoryCopyTyped(input.obj_arr, prev.obj_arr, prev.count);
|
||||||
MemoryCopyTyped(input.debug_s_arr, prev.debug_s_arr, prev.count);
|
MemoryCopyTyped(input.debug_s_arr, prev.debug_s_arr, prev.count);
|
||||||
MemoryCopyTyped(input.debug_p_arr, prev.debug_p_arr, prev.count);
|
|
||||||
MemoryCopyTyped(input.debug_t_arr, prev.debug_t_arr, prev.count);
|
MemoryCopyTyped(input.debug_t_arr, prev.debug_t_arr, prev.count);
|
||||||
MemoryCopyTyped(input.parsed_symbols, prev.parsed_symbols, prev.count);
|
MemoryCopyTyped(input.parsed_symbols, prev.parsed_symbols, prev.count);
|
||||||
MemoryCopyTyped(input.obj_to_ts, prev.obj_to_ts, prev.count);
|
MemoryCopyTyped(input.obj_to_ts, prev.obj_to_ts, prev.count);
|
||||||
@@ -494,21 +495,21 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get PCH leaf data
|
// get PCH leaf data
|
||||||
CV_DebugT *debug_p = &input.debug_p_arr[debug_p_obj_idx];
|
CV_DebugT *debug_p = &input.debug_t_arr[debug_p_obj_idx];
|
||||||
|
|
||||||
// error check LF_PRECOMP
|
// error check LF_PRECOMP
|
||||||
if (precomp.start_index > CV_MinComplexTypeIndex) { lnk_error_obj(LNK_Warning_AtypicalStartIndex, obj, "atypical start index 0x%x in LF_PRECOMP", precomp.start_index); }
|
if (precomp.start_index > CV_MinComplexTypeIndex) { lnk_error_obj(LNK_Warning_AtypicalStartIndex, obj, "atypical start index 0x%x in LF_PRECOMP", precomp.start_index); }
|
||||||
if (precomp.start_index < CV_MinComplexTypeIndex) { lnk_error_obj(LNK_Error_InvalidStartIndex, obj, "invalid start index 0x%x in LF_PRECOMP; must be >= 0x%x", precomp.start_index, CV_MinComplexTypeIndex); continue; }
|
if (precomp.start_index < CV_MinComplexTypeIndex) { lnk_error_obj(LNK_Error_InvalidStartIndex, obj, "invalid start index 0x%x in LF_PRECOMP; must be >= 0x%x", precomp.start_index, CV_MinComplexTypeIndex); continue; }
|
||||||
if (precomp.leaf_count > debug_p->count) { lnk_error_obj(LNK_Error_InvalidPrecompLeafCount, obj, "leaf count %u LF_PRECOMP exceeds leaf count %u in .debug$P in %S", precomp.leaf_count, debug_p->count, obj_arr[debug_p_obj_idx]->path); continue; }
|
if (precomp.leaf_count >= debug_p->count) { lnk_error_obj(LNK_Error_InvalidPrecompLeafCount, obj, "leaf count %u LF_PRECOMP exceeds leaf count %u in .debug$P in %S", precomp.leaf_count, debug_p->count, obj_arr[debug_p_obj_idx]->path); continue; }
|
||||||
|
|
||||||
// get LF_PRECOMP
|
// get LF_PRECOMP
|
||||||
CV_Leaf endprecomp_leaf = cv_debug_t_get_leaf(debug_p, precomp.leaf_count-1);
|
CV_Leaf endprecomp_leaf = cv_debug_t_get_leaf(debug_p, precomp.leaf_count);
|
||||||
CV_LeafEndPreComp *endprecomp = str8_deserial_get_raw_ptr(endprecomp_leaf.data, 0, sizeof(*endprecomp));
|
CV_LeafEndPreComp *endprecomp = str8_deserial_get_raw_ptr(endprecomp_leaf.data, 0, sizeof(*endprecomp));
|
||||||
|
|
||||||
// error check LF_ENDPRECOMP
|
// error check LF_ENDPRECOMP
|
||||||
if (endprecomp_leaf.kind != CV_LeafKind_ENDPRECOMP) { lnk_error_obj(LNK_Error_EndprecompNotFound, obj, "missing LF_ENDPRECOMP [0x%x] in %S", precomp.leaf_count, obj_arr[debug_p_obj_idx]->path); continue; }
|
if (endprecomp_leaf.kind != CV_LeafKind_ENDPRECOMP) { lnk_error_obj(LNK_Error_EndprecompNotFound, obj, "missing LF_ENDPRECOMP [0x%x] in %S", precomp.leaf_count, obj_arr[debug_p_obj_idx]->path); continue; }
|
||||||
if (endprecomp_leaf.data.size != sizeof(CV_LeafEndPreComp)) { lnk_error_obj(LNK_Error_IllData, obj, "invalid size 0x%x for LF_ENDPRECOMP", endprecomp_leaf.data.size); continue; }
|
if (endprecomp_leaf.data.size != sizeof(CV_LeafEndPreComp)) { lnk_error_obj(LNK_Error_IllData, obj, "invalid size 0x%x for LF_ENDPRECOMP", endprecomp_leaf.data.size); continue; }
|
||||||
if (endprecomp->sig != precomp.sig) { lnk_error_obj(LNK_Error_PrecompSigMismatch, obj, "signature mismatch between LF_PRECOMP(0x%x) and LF_ENDPRECOMP(0x%x); precomp obj %S", precomp.sig, endprecomp->sig, obj_arr[debug_p_obj_idx]->path); continue; }
|
if (endprecomp->sig != precomp.sig) { lnk_error_obj(LNK_Error_PrecompSigMismatch, obj, "PCH signature mismatch, expected 0x%x got 0x%x; PCH obj %S", precomp.sig, endprecomp->sig, obj_arr[debug_p_obj_idx]->path); continue; }
|
||||||
|
|
||||||
{ // PCH and OBJ signatures must match
|
{ // PCH and OBJ signatures must match
|
||||||
String8List symbols = cv_sub_section_from_debug_s(input.debug_s_arr[debug_p_obj_idx], CV_C13SubSectionKind_Symbols);
|
String8List symbols = cv_sub_section_from_debug_s(input.debug_s_arr[debug_p_obj_idx], CV_C13SubSectionKind_Symbols);
|
||||||
@@ -538,13 +539,13 @@ lnk_make_code_view_input(TP_Context *tp, TP_Arena *tp_arena, LNK_IO_Flags io_fla
|
|||||||
// remove CV_LeafKind_ENDPRECOMP from .debug$P
|
// remove CV_LeafKind_ENDPRECOMP from .debug$P
|
||||||
for EachIndex(i, input.debug_p_indices.count) {
|
for EachIndex(i, input.debug_p_indices.count) {
|
||||||
U64 debug_p_idx = input.debug_p_indices.v[i];
|
U64 debug_p_idx = input.debug_p_indices.v[i];
|
||||||
CV_DebugT *debug_p = &input.debug_p_arr[debug_p_idx];
|
CV_DebugT *debug_p = &input.debug_t_arr[debug_p_idx];
|
||||||
for EachIndex(i, debug_p->count) {
|
for EachIndex(i, debug_p->count) {
|
||||||
U64 lf_idx = debug_p->count - (i + 1);
|
U64 lf_idx = debug_p->count - (i + 1);
|
||||||
CV_LeafHeader *lf = cv_debug_t_get_leaf_header(debug_p, lf_idx);
|
CV_LeafHeader *lf = cv_debug_t_get_leaf_header(debug_p, lf_idx);
|
||||||
if (lf->kind == CV_LeafKind_ENDPRECOMP) {
|
if (lf->kind == CV_LeafKind_ENDPRECOMP) {
|
||||||
memory_write16(&lf->kind, CV_LeafKind_NOTYPE);
|
memory_write16(&lf->kind, CV_LeafKind_NOTYPE);
|
||||||
memory_write16(&lf->size, 0);
|
memory_write16(&lf->size, sizeof(CV_LeafKind));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -582,7 +583,7 @@ lnk_leaf_ref_from_ti(LNK_CodeViewInput *input, U32 obj_idx, CV_TypeIndexSource s
|
|||||||
if (contains_1u64(debug_t->pch_ti_range[source], ti)) {
|
if (contains_1u64(debug_t->pch_ti_range[source], ti)) {
|
||||||
leaf_ref = (LNK_LeafRef){
|
leaf_ref = (LNK_LeafRef){
|
||||||
.obj_idx = debug_t->pch_obj_idx,
|
.obj_idx = debug_t->pch_obj_idx,
|
||||||
.leaf_idx = cv_leaf_idx_from_ti(&input->debug_p_arr[debug_t->pch_obj_idx], source, ti)
|
.leaf_idx = cv_leaf_idx_from_ti(&input->debug_t_arr[debug_t->pch_obj_idx], source, ti)
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
U64 ts_idx = input->obj_to_ts[obj_idx];
|
U64 ts_idx = input->obj_to_ts[obj_idx];
|
||||||
@@ -1366,17 +1367,16 @@ lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input)
|
|||||||
{
|
{
|
||||||
ProfBegin("Alloc Hashes");
|
ProfBegin("Alloc Hashes");
|
||||||
U32Array indices[] = {
|
U32Array indices[] = {
|
||||||
input->int_obj_indices,
|
|
||||||
input->debug_p_indices,
|
input->debug_p_indices,
|
||||||
input->type_server_indices
|
input->int_obj_indices,
|
||||||
// TODO: explain
|
input->type_server_indices,
|
||||||
// input->ext_obj_indices,
|
|
||||||
};
|
};
|
||||||
for EachElement(i, indices) {
|
for EachElement(i, indices) {
|
||||||
for EachIndex(k, indices[i].count) {
|
for EachIndex(k, indices[i].count) {
|
||||||
U64 obj_idx = indices[i].v[k];
|
U64 obj_idx = indices[i].v[k];
|
||||||
|
CV_DebugT *debug_t = &input->debug_t_arr[obj_idx];
|
||||||
CV_DebugH *debug_h = &input->debug_h_arr[obj_idx];
|
CV_DebugH *debug_h = &input->debug_h_arr[obj_idx];
|
||||||
debug_h->count = input->debug_t_arr[obj_idx].count;
|
debug_h->count = debug_t->count;
|
||||||
debug_h->v = push_array(scratch.arena, U64, debug_h->count);
|
debug_h->v = push_array(scratch.arena, U64, debug_h->count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1423,7 +1423,7 @@ lnk_merge_types(TP_Context *tp, TP_Arena *tp_temp, LNK_CodeViewInput *input)
|
|||||||
for EachIndex(obj_idx, input->count) { total_count += input->debug_t_arr[obj_idx].source_counts[ti_source]; }
|
for EachIndex(obj_idx, input->count) { total_count += input->debug_t_arr[obj_idx].source_counts[ti_source]; }
|
||||||
|
|
||||||
task.leaf_ht_arr[ti_source].cap = total_count;
|
task.leaf_ht_arr[ti_source].cap = total_count;
|
||||||
task.leaf_ht_arr[ti_source].cap = (task.leaf_ht_arr[ti_source].cap * 13) / 10; // * 1.3
|
task.leaf_ht_arr[ti_source].cap = 1 + ((task.leaf_ht_arr[ti_source].cap * 13) / 10); // * 1.3
|
||||||
task.leaf_ht_arr[ti_source].bucket_arr = push_array(scratch.arena, LNK_LeafRef *, task.leaf_ht_arr[ti_source].cap);
|
task.leaf_ht_arr[ti_source].bucket_arr = push_array(scratch.arena, LNK_LeafRef *, task.leaf_ht_arr[ti_source].cap);
|
||||||
|
|
||||||
#if PROFILE_TELEMETRY
|
#if PROFILE_TELEMETRY
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ typedef struct
|
|||||||
U64 count;
|
U64 count;
|
||||||
LNK_Obj **obj_arr;
|
LNK_Obj **obj_arr;
|
||||||
CV_DebugS *debug_s_arr;
|
CV_DebugS *debug_s_arr;
|
||||||
CV_DebugT *debug_p_arr;
|
|
||||||
CV_DebugT *debug_t_arr;
|
CV_DebugT *debug_t_arr;
|
||||||
CV_DebugH *debug_h_arr;
|
CV_DebugH *debug_h_arr;
|
||||||
U64 *obj_to_ts;
|
U64 *obj_to_ts;
|
||||||
|
|||||||
+13
-6
@@ -213,20 +213,27 @@ t_invoke(String8 exe_path, String8 cmdline, U64 timeout)
|
|||||||
return t_invoke_(exe_path, cmdline, timeout, 0, 0);
|
return t_invoke_(exe_path, cmdline, timeout, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal B32
|
internal String8
|
||||||
t_match_line(String8 *output, String8 expected_line)
|
t_chop_line(String8 *output)
|
||||||
{
|
{
|
||||||
U64 new_line_pos = str8_find_needle(*output, 0, str8_lit("\n"), 0);
|
U64 new_line_pos = str8_find_needle(*output, 0, str8_lit("\n"), 0);
|
||||||
String8 line = str8_prefix(*output, new_line_pos);
|
String8 line = str8_prefix(*output, new_line_pos);
|
||||||
if (str8_ends_with(line, str8_lit("\r"), 0)) {
|
if (str8_ends_with(line, str8_lit("\r"), 0)) {
|
||||||
line = str8_chop(line, 1);
|
line = str8_chop(line, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
B32 is_match = str8_match(line, expected_line, 0);
|
|
||||||
if (is_match) {
|
|
||||||
*output = str8_skip(*output, new_line_pos + 1);
|
*output = str8_skip(*output, new_line_pos + 1);
|
||||||
}
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal B32
|
||||||
|
t_match_line(String8 *output, String8 expected_line)
|
||||||
|
{
|
||||||
|
String8 before_chop = *output;
|
||||||
|
String8 line = t_chop_line(output);
|
||||||
|
B32 is_match = str8_match(line, expected_line, 0);
|
||||||
|
if ( ! is_match) {
|
||||||
|
*output = before_chop;
|
||||||
|
}
|
||||||
return is_match;
|
return is_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3940,12 +3940,323 @@ T_BeginTest(long_section_name)
|
|||||||
}
|
}
|
||||||
T_EndTest;
|
T_EndTest;
|
||||||
|
|
||||||
|
T_BeginTest(debug_p_sig_mismatch)
|
||||||
|
{
|
||||||
|
String8 a_obj_name = str8_lit("a.obj");
|
||||||
|
String8 b_obj_name = str8_lit("b.obj");
|
||||||
|
U32 a_sig = 0xCAFEBABE;
|
||||||
|
U32 b_sig = 0xDEADBEEF;
|
||||||
|
|
||||||
|
String8 a_debug_s;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_C13SubSectionHeader *ss_header = str8_serial_push_size(scratch.arena, &srl, sizeof(*ss_header));
|
||||||
|
U64 ss_start_off = srl.total_size;
|
||||||
|
|
||||||
|
CV_SymObjName obj_name = {0};
|
||||||
|
obj_name.sig = a_sig;
|
||||||
|
String8 obj_name_string = a_obj_name;
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &srl, obj_name_string);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
|
||||||
|
|
||||||
|
String8 comp3_data = cv_make_comp3(scratch.arena,
|
||||||
|
0,
|
||||||
|
CV_Language_C,
|
||||||
|
CV_Arch_X64,
|
||||||
|
/* ver_fe_major */ 0,
|
||||||
|
/* ver_fe_minor */ 0,
|
||||||
|
/* ver_fe_build */ 0,
|
||||||
|
/* ver_feqfe */ 0,
|
||||||
|
/* ver_major */ 14,
|
||||||
|
/* ver_minor */ 36,
|
||||||
|
/* ver_build */ 32537,
|
||||||
|
/* ver_qfe */ 0,
|
||||||
|
str8_lit(BUILD_TITLE));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + comp3_data.size);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_COMPILE3);
|
||||||
|
str8_serial_push_string(scratch.arena, &srl, comp3_data);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
|
||||||
|
|
||||||
|
ss_header->kind = CV_C13SubSectionKind_Symbols;
|
||||||
|
ss_header->size = srl.total_size - ss_start_off;
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_C13SubSectionAlign);
|
||||||
|
|
||||||
|
a_debug_s = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
String8 a_debug_p;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
// signature
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
// duplicate in a.obj
|
||||||
|
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(ptr));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &ptr);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
// unique procedure type
|
||||||
|
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearPascal };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(proc));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &proc);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
// PCH ender
|
||||||
|
CV_LeafEndPreComp endprecomp = { .sig = a_sig };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(endprecomp));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_ENDPRECOMP);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &endprecomp);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
a_debug_p = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 b_debug_s;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_C13SubSectionHeader *ss_header = str8_serial_push_size(scratch.arena, &srl, sizeof(*ss_header));
|
||||||
|
U64 ss_start_off = srl.total_size;
|
||||||
|
|
||||||
|
CV_SymObjName obj_name = {0};
|
||||||
|
obj_name.sig = b_sig;
|
||||||
|
String8 obj_name_string = a_obj_name;
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &srl, obj_name_string);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
|
||||||
|
|
||||||
|
String8 comp3_data = cv_make_comp3(scratch.arena,
|
||||||
|
0,
|
||||||
|
CV_Language_C,
|
||||||
|
CV_Arch_X64,
|
||||||
|
/* ver_fe_major */ 0,
|
||||||
|
/* ver_fe_minor */ 0,
|
||||||
|
/* ver_fe_build */ 0,
|
||||||
|
/* ver_feqfe */ 0,
|
||||||
|
/* ver_major */ 14,
|
||||||
|
/* ver_minor */ 36,
|
||||||
|
/* ver_build */ 32537,
|
||||||
|
/* ver_qfe */ 0,
|
||||||
|
str8_lit(BUILD_TITLE));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + comp3_data.size);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_COMPILE3);
|
||||||
|
str8_serial_push_string(scratch.arena, &srl, comp3_data);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
|
||||||
|
|
||||||
|
ss_header->kind = CV_C13SubSectionKind_Symbols;
|
||||||
|
ss_header->size = srl.total_size - ss_start_off;
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_C13SubSectionAlign);
|
||||||
|
|
||||||
|
b_debug_s = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 b_debug_t;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_LeafPreComp precomp = { .start_index = CV_MinComplexTypeIndex, .count = 2, sig = b_sig };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(precomp) + a_obj_name.size + 1);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PRECOMP);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &precomp);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &srl, a_obj_name);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &ptr);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &proc);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
b_debug_t = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 a_obj;
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$P"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, a_debug_p);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$S"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, a_debug_s);
|
||||||
|
a_obj = coff_obj_writer_serialize(scratch.arena, cow);
|
||||||
|
coff_obj_writer_release(&cow);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 b_obj;
|
||||||
|
{
|
||||||
|
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$T"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, b_debug_t);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$S"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, b_debug_s);
|
||||||
|
b_obj = coff_obj_writer_serialize(scratch.arena, cow);
|
||||||
|
coff_obj_writer_release(&cow);
|
||||||
|
}
|
||||||
|
|
||||||
|
T_Ok(t_write_file(str8_lit("a.obj"), a_obj));
|
||||||
|
T_Ok(t_write_file(str8_lit("b.obj"), b_obj));
|
||||||
|
T_Ok(t_write_entry_obj());
|
||||||
|
|
||||||
|
String8 output = {0};
|
||||||
|
t_invoke_(t_radlink_path(), str8_lit("/subsystem:console /entry:entry /out:a.exe /debug:full a.obj b.obj entry.obj"), max_U64, scratch.arena, &output);
|
||||||
|
T_Ok(g_last_exit_code == 0);
|
||||||
|
|
||||||
|
B32 found_error = 0;
|
||||||
|
String8 a_obj_path = t_make_file_path(scratch.arena, str8_lit("a.obj"));
|
||||||
|
String8 b_obj_path = t_make_file_path(scratch.arena, str8_lit("b.obj"));
|
||||||
|
String8 expected_line = str8f(scratch.arena, "Error(%03d): %S: PCH signature mismatch, expected 0x%x got 0x%x; PCH obj %S", LNK_Error_PrecompSigMismatch, b_obj_path, b_sig, a_sig, a_obj_path);
|
||||||
|
while (output.size) {
|
||||||
|
String8 line = t_chop_line(&output);
|
||||||
|
found_error = str8_match(line, expected_line, StringMatchFlag_CaseInsensitive);
|
||||||
|
if (found_error) { break; }
|
||||||
|
}
|
||||||
|
T_Ok(found_error);
|
||||||
|
}
|
||||||
|
T_EndTest;
|
||||||
|
|
||||||
|
T_BeginTest(debug_p_and_debug_t_in_obj)
|
||||||
|
{
|
||||||
|
U32 pch_sig = 0xCAFEBABE;
|
||||||
|
String8 pch_obj_name = str8_lit("pch.obj");
|
||||||
|
|
||||||
|
String8 pch_debug_s;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_C13SubSectionHeader *ss_header = str8_serial_push_size(scratch.arena, &srl, sizeof(*ss_header));
|
||||||
|
U64 ss_start_off = srl.total_size;
|
||||||
|
|
||||||
|
CV_SymObjName obj_name = {0};
|
||||||
|
obj_name.sig = pch_sig;
|
||||||
|
String8 obj_name_string = pch_obj_name;
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &srl, obj_name_string);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_SymbolAlign);
|
||||||
|
|
||||||
|
ss_header->kind = CV_C13SubSectionKind_Symbols;
|
||||||
|
ss_header->size = srl.total_size - ss_start_off;
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_C13SubSectionAlign);
|
||||||
|
|
||||||
|
pch_debug_s = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 pch_debug_p;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
// signature
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(ptr));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &ptr);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
// PCH ender
|
||||||
|
CV_LeafEndPreComp endprecomp = { .sig = pch_sig };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(endprecomp));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_ENDPRECOMP);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &endprecomp);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
pch_debug_p = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
String8 pch_debug_t;
|
||||||
|
{
|
||||||
|
String8List srl;
|
||||||
|
str8_serial_begin(scratch.arena, &srl);
|
||||||
|
|
||||||
|
CV_Signature sig = CV_Signature_C13;
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &sig);
|
||||||
|
|
||||||
|
CV_LeafPreComp precomp = { .start_index = CV_MinComplexTypeIndex, .count = 1, sig = pch_sig };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(precomp) + pch_obj_name.size + 1);
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PRECOMP);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &precomp);
|
||||||
|
str8_serial_push_cstr(scratch.arena, &srl, pch_obj_name);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
CV_LeafPointer ptr = { .itype = CV_BasicType_VOID };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafPointer));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_POINTER);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &ptr);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
CV_LeafProcedure proc = { .ret_itype = 0x1000, .call_kind = CV_CallKind_NearC };
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_LeafKind) + sizeof(CV_LeafProcedure));
|
||||||
|
str8_serial_push_u16(scratch.arena, &srl, CV_LeafKind_PROCEDURE);
|
||||||
|
str8_serial_push_struct(scratch.arena, &srl, &proc);
|
||||||
|
str8_serial_push_align(scratch.arena, &srl, CV_LeafAlign);
|
||||||
|
|
||||||
|
pch_debug_t = str8_serial_end(scratch.arena, &srl);
|
||||||
|
}
|
||||||
|
|
||||||
|
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$P"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, pch_debug_p);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$T"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, pch_debug_t);
|
||||||
|
coff_obj_writer_push_section(cow, str8_lit(".debug$S"), PE_DEBUG_SECTION_FLAGS|COFF_SectionFlag_Align1Bytes, pch_debug_s);
|
||||||
|
String8 raw_coff = coff_obj_writer_serialize(scratch.arena, cow);
|
||||||
|
coff_obj_writer_release(&cow);
|
||||||
|
|
||||||
|
T_Ok(t_write_file(str8_lit("pch.obj"), raw_coff));
|
||||||
|
T_Ok(t_write_entry_obj());
|
||||||
|
String8 output = {0};
|
||||||
|
t_invoke_(t_radlink_path(), str8_lit("/subsystem:console /entry:entry /out:a.exe /debug:full pch.obj entry.obj"), max_U64, scratch.arena, &output);
|
||||||
|
T_Ok(g_last_exit_code == 0);
|
||||||
|
|
||||||
|
B32 found_warning = 0;
|
||||||
|
String8 pch_obj_path = t_make_file_path(scratch.arena, str8_lit("pch.obj"));
|
||||||
|
String8 expected_line = str8f(scratch.arena, "Warning(%03d): %S: multiple sections with debug types detected, obj must have either .debug$T or .debug$P; discarding both sections", LNK_Warning_MultipleDebugTAndDebugP, pch_obj_path);
|
||||||
|
while (output.size) {
|
||||||
|
String8 line = t_chop_line(&output);
|
||||||
|
found_warning = str8_match(line, expected_line, StringMatchFlag_CaseInsensitive);
|
||||||
|
if (found_warning) { break; }
|
||||||
|
}
|
||||||
|
T_Ok(found_warning);
|
||||||
|
}
|
||||||
|
T_EndTest;
|
||||||
|
|
||||||
T_BeginTest(merge_duplicate_types)
|
T_BeginTest(merge_duplicate_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
U32 pch_sig = 0xCAFEBABE;
|
U32 pch_sig = 0xCAFEBABE;
|
||||||
String8 pch_obj_name = str8_lit("C:\\devel\\raddebugger\\build\\torture\\merge_duplicate_types\\pch.obj");
|
String8 pch_obj_name = str8_lit("pch.obj");
|
||||||
String8 a_obj_name = str8_lit("C:\\devel\\raddebugger\\build\\torture\\merge_duplicate_types\\a.obj");
|
String8 a_obj_name = str8_lit("a.obj");
|
||||||
|
String8 c_obj_name = str8_lit("c.obj");
|
||||||
|
|
||||||
String8 pch_debug_s;
|
String8 pch_debug_s;
|
||||||
{
|
{
|
||||||
@@ -4136,7 +4447,7 @@ T_BeginTest(merge_duplicate_types)
|
|||||||
// S_OBJNAME
|
// S_OBJNAME
|
||||||
CV_SymObjName obj_name = {0};
|
CV_SymObjName obj_name = {0};
|
||||||
obj_name.sig = pch_sig;
|
obj_name.sig = pch_sig;
|
||||||
String8 obj_name_string = a_obj_name;
|
String8 obj_name_string = c_obj_name;
|
||||||
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
|
str8_serial_push_u16(scratch.arena, &srl, sizeof(CV_SymKind) + sizeof(obj_name) + obj_name_string.size + 1);
|
||||||
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
|
str8_serial_push_u16(scratch.arena, &srl, CV_SymKind_OBJNAME);
|
||||||
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
|
str8_serial_push_struct(scratch.arena, &srl, &obj_name);
|
||||||
@@ -4227,7 +4538,7 @@ T_BeginTest(merge_duplicate_types)
|
|||||||
T_Ok(t_write_file(str8_lit("b.obj"), b_obj));
|
T_Ok(t_write_file(str8_lit("b.obj"), b_obj));
|
||||||
T_Ok(t_write_file(str8_lit("c.obj"), c_obj));
|
T_Ok(t_write_file(str8_lit("c.obj"), c_obj));
|
||||||
|
|
||||||
t_invoke_linkerf("/subsystem:console /entry:entry /debug:full /out:a.exe pch.obj a.obj c.obj entry.obj");
|
t_invoke_linkerf("/subsystem:console /entry:entry /debug:full /out:a.exe pch.obj a.obj b.obj c.obj entry.obj");
|
||||||
T_Ok(g_last_exit_code == 0);
|
T_Ok(g_last_exit_code == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4247,7 +4558,7 @@ T_BeginTest(merge_duplicate_types)
|
|||||||
PDB_TpiParsed *tpi = pdb_tpi_from_data(scratch.arena, tpi_data);
|
PDB_TpiParsed *tpi = pdb_tpi_from_data(scratch.arena, tpi_data);
|
||||||
|
|
||||||
U64 type_count = tpi->itype_opl - tpi->itype_first;
|
U64 type_count = tpi->itype_opl - tpi->itype_first;
|
||||||
T_Ok(type_count == 4);
|
T_Ok(type_count == 5);
|
||||||
|
|
||||||
CV_DebugT debug_t = cv_debug_t_from_data(scratch.arena, pdb_leaf_data_from_tpi(tpi), 4);
|
CV_DebugT debug_t = cv_debug_t_from_data(scratch.arena, pdb_leaf_data_from_tpi(tpi), 4);
|
||||||
T_Ok(debug_t.count == type_count);
|
T_Ok(debug_t.count == type_count);
|
||||||
@@ -4267,13 +4578,23 @@ T_BeginTest(merge_duplicate_types)
|
|||||||
T_Ok(proc_leaf.kind == CV_LeafKind_PROCEDURE);
|
T_Ok(proc_leaf.kind == CV_LeafKind_PROCEDURE);
|
||||||
T_Ok(proc_leaf.data.size == sizeof(CV_LeafProcedure));
|
T_Ok(proc_leaf.data.size == sizeof(CV_LeafProcedure));
|
||||||
|
|
||||||
|
CV_LeafProcedure *proc = (CV_LeafProcedure *)proc_leaf.data.str;
|
||||||
|
T_Ok(proc->ret_itype == 0x1000);
|
||||||
|
T_Ok(proc->call_kind == CV_CallKind_NearPascal);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
CV_Leaf proc_leaf = cv_debug_t_get_leaf(&debug_t, 2);
|
||||||
|
T_Ok(proc_leaf.kind == CV_LeafKind_PROCEDURE);
|
||||||
|
T_Ok(proc_leaf.data.size == sizeof(CV_LeafProcedure));
|
||||||
|
|
||||||
CV_LeafProcedure *proc = (CV_LeafProcedure *)proc_leaf.data.str;
|
CV_LeafProcedure *proc = (CV_LeafProcedure *)proc_leaf.data.str;
|
||||||
T_Ok(proc->ret_itype == 0x1000);
|
T_Ok(proc->ret_itype == 0x1000);
|
||||||
T_Ok(proc->call_kind == CV_CallKind_NearC);
|
T_Ok(proc->call_kind == CV_CallKind_NearC);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CV_Leaf ptr_leaf = cv_debug_t_get_leaf(&debug_t, 2);
|
CV_Leaf ptr_leaf = cv_debug_t_get_leaf(&debug_t, 3);
|
||||||
T_Ok(ptr_leaf.kind == CV_LeafKind_POINTER);
|
T_Ok(ptr_leaf.kind == CV_LeafKind_POINTER);
|
||||||
T_Ok(ptr_leaf.data.size == sizeof(CV_LeafPointer));
|
T_Ok(ptr_leaf.data.size == sizeof(CV_LeafPointer));
|
||||||
|
|
||||||
@@ -4283,12 +4604,12 @@ T_BeginTest(merge_duplicate_types)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CV_Leaf proc_leaf = cv_debug_t_get_leaf(&debug_t, 3);
|
CV_Leaf proc_leaf = cv_debug_t_get_leaf(&debug_t, 4);
|
||||||
T_Ok(proc_leaf.kind == CV_LeafKind_PROCEDURE);
|
T_Ok(proc_leaf.kind == CV_LeafKind_PROCEDURE);
|
||||||
T_Ok(proc_leaf.data.size == sizeof(CV_LeafProcedure));
|
T_Ok(proc_leaf.data.size == sizeof(CV_LeafProcedure));
|
||||||
|
|
||||||
CV_LeafProcedure *proc = (CV_LeafProcedure *)proc_leaf.data.str;
|
CV_LeafProcedure *proc = (CV_LeafProcedure *)proc_leaf.data.str;
|
||||||
T_Ok(proc->ret_itype == 0x1002);
|
T_Ok(proc->ret_itype == 0x1003);
|
||||||
T_Ok(proc->call_kind == CV_CallKind_NearC);
|
T_Ok(proc->call_kind == CV_CallKind_NearC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user