mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 09:18:09 +00:00
test stripped PDB
This commit is contained in:
@@ -196,11 +196,13 @@ cv_write_symbol_buf(String8Node *buf, U64 *buf_pos, CV_Symbol *symbol, U64 align
|
||||
{
|
||||
CV_SymbolHeader header = { .size = sizeof(CV_SymKind) + symbol->data.size, .kind = symbol->kind };
|
||||
U64 pad_size = AlignPadPow2(header.size + sizeof(CV_SymSize), align);
|
||||
header.size += pad_size;
|
||||
|
||||
U64 write_size = 0;
|
||||
write_size += str8_buffer_write(buf, buf_pos, str8_struct(&header));
|
||||
write_size += str8_buffer_write(buf, buf_pos, symbol->data);
|
||||
write_size += str8_buffer_write_zeroes(buf, buf_pos, pad_size);
|
||||
Assert(write_size == header.size + sizeof(CV_SymSize) + pad_size);
|
||||
|
||||
return write_size;
|
||||
}
|
||||
|
||||
|
||||
+6
-8
@@ -5320,7 +5320,8 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
||||
if (cv_is_lproc(symbol)) {
|
||||
proc_count += 1;
|
||||
proc_size += AlignPow2(symbol.data.size, CV_SymbolAlign);
|
||||
proc_size += AlignPow2(sizeof(CV_SymbolHeader) + symbol.data.size, CV_SymbolAlign);
|
||||
proc_size += AlignPow2(sizeof(CV_SymbolHeader), CV_SymbolAlign); // S_END
|
||||
}
|
||||
}
|
||||
section += 1;
|
||||
@@ -5329,7 +5330,7 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
if (proc_count) {
|
||||
U64 end_count = proc_count;
|
||||
U64 symbol_count = proc_count + end_count;
|
||||
U64 buffer_size = proc_size + sizeof(CV_SymbolHeader) * symbol_count;
|
||||
U64 buffer_size = proc_size;
|
||||
U8 *buffer = push_array(scratch.arena, U8, buffer_size);
|
||||
U64 buffer_cursor = 0;
|
||||
|
||||
@@ -5339,13 +5340,10 @@ lnk_run(TP_Context *tp, TP_Arena *arena, LNK_Config *config)
|
||||
TryReadBreak(cv_read_symbol(n->string, cursor, CV_SymbolAlign, &symbol), cursor);
|
||||
if (symbol.kind == CV_SymKind_SKIP) { continue; }
|
||||
if (cv_is_lproc(symbol)) {
|
||||
CV_SymProc32 *src_proc = (CV_SymProc32 *)symbol.data.str;
|
||||
src_proc->itype = 0;
|
||||
|
||||
CV_Symbol end_symbol = { .kind = CV_SymKind_END };
|
||||
|
||||
CV_SymProc32 *src_proc = str8_deserial_get_raw_ptr(symbol.data, 0, sizeof(*src_proc));
|
||||
memory_write32(&src_proc->itype, 0); // strip type index
|
||||
buffer_cursor += cv_write_symbol(buffer, buffer_cursor, buffer_size, &symbol, CV_SymbolAlign);
|
||||
buffer_cursor += cv_write_symbol(buffer, buffer_cursor, buffer_size, &end_symbol, CV_SymbolAlign);
|
||||
buffer_cursor += cv_write_symbol(buffer, buffer_cursor, buffer_size, &(CV_Symbol){ .kind = CV_SymKind_END }, CV_SymbolAlign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -2411,18 +2411,19 @@ lnk_build_pdb(TP_Context *tp, TP_Arena *tp_arena, String8 image_data, LNK_Config
|
||||
cv_string_hash_table_assign_buffer_offsets(tp, task.string_ht);
|
||||
ProfEnd();
|
||||
|
||||
ProfScope ("Alloc Modules") for EachIndex(obj_idx, cv->obj_count) { task.mod_arr[obj_idx] = dbi_push_module(task.pdb->dbi, cv->obj_arr[obj_idx]->path, lnk_obj_get_lib_path(cv->obj_arr[obj_idx])); }
|
||||
ProfScope("Move Global Symbols") tp_for_parallel(tp, 0, tp->worker_count, lnk_move_global_symbols_to_gsi, &task);
|
||||
{
|
||||
PDB_Context *pdb = task.pdb;
|
||||
PDB_DbiContext *dbi = pdb->dbi;
|
||||
dbi->globals_sn = msf_stream_alloc(pdb->msf);
|
||||
dbi->publics_sn = msf_stream_alloc(pdb->msf);
|
||||
dbi->symbols_sn = msf_stream_alloc(pdb->msf);
|
||||
psi_build(tp, pdb->psi, pdb->msf, dbi->publics_sn, dbi->symbols_sn);
|
||||
gsi_build(tp, pdb->gsi, pdb->msf, dbi->globals_sn, dbi->symbols_sn);
|
||||
}
|
||||
ProfScope("Write Modules") tp_for_parallel(tp, 0, tp->worker_count, lnk_write_pdb_modules, &task);
|
||||
ProfScope ("Alloc Modules")
|
||||
for EachIndex(obj_idx, cv->obj_count) {
|
||||
task.mod_arr[obj_idx] = dbi_push_module(task.pdb->dbi, cv->obj_arr[obj_idx]->path, lnk_obj_get_lib_path(cv->obj_arr[obj_idx]));
|
||||
}
|
||||
|
||||
ProfScope("Move Global Symbols")
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_move_global_symbols_to_gsi, &task);
|
||||
|
||||
ProfScope("Build GSI and PSI")
|
||||
pdb_build_gsi_psi(tp, task.pdb);
|
||||
|
||||
ProfScope("Write Modules")
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_write_pdb_modules, &task);
|
||||
|
||||
ProfBegin("Add string tables");
|
||||
pdb_strtab_add_cv_string_hash_table(&task.pdb->info->strtab, task.string_ht);
|
||||
|
||||
@@ -3134,6 +3134,24 @@ pdb_get_guid(PDB_Context *pdb)
|
||||
return pdb->info->guid;
|
||||
}
|
||||
|
||||
internal void
|
||||
pdb_build_gsi_psi(TP_Context *tp, PDB_Context *pdb)
|
||||
{
|
||||
PDB_DbiContext *dbi = pdb->dbi;
|
||||
|
||||
if (pdb->psi->gsi->symbol_count) {
|
||||
if (dbi->publics_sn == MSF_INVALID_STREAM_NUMBER) { dbi->publics_sn = msf_stream_alloc(pdb->msf); }
|
||||
if (dbi->symbols_sn == MSF_INVALID_STREAM_NUMBER) { dbi->symbols_sn = msf_stream_alloc(pdb->msf); }
|
||||
psi_build(tp, pdb->psi, pdb->msf, dbi->publics_sn, dbi->symbols_sn);
|
||||
}
|
||||
|
||||
if (pdb->gsi->symbol_count) {
|
||||
if (dbi->globals_sn == MSF_INVALID_STREAM_NUMBER) { dbi->globals_sn = msf_stream_alloc(pdb->msf); }
|
||||
if (dbi->symbols_sn == MSF_INVALID_STREAM_NUMBER) { dbi->symbols_sn = msf_stream_alloc(pdb->msf); }
|
||||
gsi_build(tp, pdb->gsi, pdb->msf, dbi->globals_sn, dbi->symbols_sn);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTable string_ht, B32 build_gsi, B32 is_stripped)
|
||||
{
|
||||
@@ -3151,17 +3169,7 @@ pdb_build(TP_Context *tp, TP_Arena *pool_temp, PDB_Context *pdb, CV_StringHashTa
|
||||
}
|
||||
|
||||
if (build_gsi) {
|
||||
if (dbi->globals_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->globals_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->publics_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->publics_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
if (dbi->symbols_sn == MSF_INVALID_STREAM_NUMBER) {
|
||||
dbi->symbols_sn = msf_stream_alloc(pdb->msf);
|
||||
}
|
||||
psi_build(tp, pdb->psi, pdb->msf, dbi->publics_sn, dbi->symbols_sn);
|
||||
gsi_build(tp, pdb->gsi, pdb->msf, dbi->globals_sn, dbi->symbols_sn);
|
||||
pdb_build_gsi_psi(tp, pdb);
|
||||
}
|
||||
|
||||
dbi_build(tp, pdb->dbi, pdb->msf, PDB_FixedStream_Dbi, string_ht, is_stripped);
|
||||
|
||||
@@ -4687,9 +4687,9 @@ TEST(validate_info_stream)
|
||||
0x6f, 0x00, 0x74, 0x68, 0x72, 0x65, 0x65, 0x00, 0x66, 0x6f, 0x75, 0x72, 0x00, 0x66, 0x69, 0x76, 0x65, 0x00, 0x2f,
|
||||
0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13,
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x51, 0x33, 0x01
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x51, 0x33, 0x01,
|
||||
};
|
||||
T_Ok(str8_match(info_data, str8_array_fixed(expected_info_data), 0));
|
||||
|
||||
@@ -4742,7 +4742,9 @@ TEST(validate_gsi)
|
||||
CV_Symbol test_symbol = {0};
|
||||
U64 test_symbol_size = cv_read_symbol(str8_skip(symbol_data, symbol_off), 0, 1, &test_symbol);
|
||||
T_Ok(test_symbol_size > 0);
|
||||
T_Ok(cv_symbol_match(test_symbol, symbols[i]));
|
||||
|
||||
String8 test_symbol_name = cv_name_from_symbol(test_symbol.kind, test_symbol.data);
|
||||
T_Ok(str8_match(test_symbol_name, string, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4904,6 +4906,106 @@ TEST(validate_psi)
|
||||
T_Ok(pub32_count > 0);
|
||||
}
|
||||
|
||||
TEST(pdbstripped)
|
||||
{
|
||||
String8 debug_obj;
|
||||
{
|
||||
String8 raw_symbols[] = {
|
||||
cv_make_symbol(arena, CV_SymKind_OBJNAME, cv_make_obj_name(arena, str8_lit("debug.obj"), 0x123)),
|
||||
cv_make_symbol(arena, CV_SymKind_GPROC32_ID, cv_make_proc32(arena, (CV_SymProc32){0}, str8_lit("global_proc"))),
|
||||
cv_make_symbol(arena, CV_SymKind_PROC_ID_END, cv_make_end(arena)),
|
||||
|
||||
cv_make_symbol(arena, CV_SymKind_UDT, cv_make_udt(arena, (CV_SymUDT){0}, str8_lit("global_typedef"))),
|
||||
|
||||
cv_make_symbol(arena, CV_SymKind_LPROC32_ID, cv_make_proc32(arena, (CV_SymProc32){0}, str8_lit("local_proc"))),
|
||||
cv_make_symbol(arena, CV_SymKind_UDT, cv_make_udt(arena, (CV_SymUDT){0}, str8_lit("local_typedef"))),
|
||||
cv_make_symbol(arena, CV_SymKind_PROC_ID_END, cv_make_end(arena)),
|
||||
};
|
||||
|
||||
CV_Symbol symbols[ArrayCount(raw_symbols)] = {0};
|
||||
for EachElement(i, raw_symbols) { symbols[i] = cv_symbol_from_ptr(raw_symbols[i].str); }
|
||||
|
||||
CV_DebugS debug_s = {0};
|
||||
for EachElement(i, symbols) { str8_list_push(arena, &debug_s.data_list[CV_C13SubSectionIdxKind_Symbols], cv_data_from_symbol(arena, &symbols[i], CV_SymbolAlign)); }
|
||||
String8List raw_debug_s_list = cv_data_from_debug_s_c13(arena, &debug_s, 1);
|
||||
String8 raw_debug_s = str8_list_join(arena, &raw_debug_s_list, 0);
|
||||
|
||||
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||
t_push_debug_s_section(cow, raw_debug_s);
|
||||
debug_obj = coff_obj_writer_serialize(arena, cow);
|
||||
coff_obj_writer_release(&cow);
|
||||
}
|
||||
|
||||
String8 pub_obj;
|
||||
{
|
||||
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||
COFF_ObjSection *text = coff_obj_writer_push_section(cow, str8_lit(".text"), PE_TEXT_SECTION_FLAGS, str8_lit("FOOBAR"));
|
||||
COFF_ObjSection *data = coff_obj_writer_push_section(cow, str8_lit(".data"), PE_DATA_SECTION_FLAGS, str8_lit("QWE"));
|
||||
coff_obj_writer_push_symbol_extern_func(cow, str8_lit("global_func"), 1, text);
|
||||
coff_obj_writer_push_symbol_extern(cow, str8_lit("global_var"), 1, data);
|
||||
coff_obj_writer_push_symbol_static(cow, str8_lit("static_var"), 1, data);
|
||||
pub_obj = coff_obj_writer_serialize(arena, cow);
|
||||
coff_obj_writer_release(&cow);
|
||||
}
|
||||
|
||||
T_Ok(t_write_file(str8_lit("debug.obj"), debug_obj));
|
||||
T_Ok(t_write_file(str8_lit("pub.obj"), pub_obj));
|
||||
T_Ok(t_write_entry_obj());
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /debug:full /out:a.exe /pdbstripped:a.stripped.pdb entry.obj pub.obj debug.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
|
||||
String8 raw_pdb = t_read_file(arena, str8_lit("a.stripped.pdb"));
|
||||
MSF_Parsed *msf = msf_parsed_from_data(arena, raw_pdb);
|
||||
String8 dbi_data = msf_data_from_stream(msf, PDB_FixedStream_Dbi);
|
||||
PDB_DbiParsed *dbi = pdb_dbi_from_data(arena, dbi_data);
|
||||
|
||||
String8 mods_data = pdb_data_from_dbi_range(dbi, PDB_DbiRange_ModuleInfo);
|
||||
PDB_CompUnitArray *mods = pdb_comp_unit_array_from_data(arena, mods_data);
|
||||
T_Ok(mods->count > 0);
|
||||
|
||||
// modules must contain only stubs for static procs
|
||||
for EachIndex(i, mods->count) {
|
||||
PDB_CompUnit *mod = mods->units[i];
|
||||
U64 sym_data_size = mod->range_off[PDB_DbiCompUnitRange_Symbols + 1] - mod->range_off[PDB_DbiCompUnitRange_Symbols];
|
||||
U64 c11_data_size = mod->range_off[PDB_DbiCompUnitRange_C11 + 1] - mod->range_off[PDB_DbiCompUnitRange_C11];
|
||||
U64 c13_data_size = mod->range_off[PDB_DbiCompUnitRange_C13 + 1] - mod->range_off[PDB_DbiCompUnitRange_C13];
|
||||
T_Ok(c11_data_size == 0);
|
||||
T_Ok(c13_data_size == 0);
|
||||
if (str8_match(str8_skip_last_slash(mod->obj_name), str8_lit("debug.obj"), 0)) {
|
||||
T_Ok(sym_data_size > 0);
|
||||
} else {
|
||||
T_Ok(sym_data_size == 0);
|
||||
}
|
||||
|
||||
String8 mod_data = msf_data_from_stream(msf, mod->sn);
|
||||
String8 sym_data = str8_substr(mod_data, r1u64(mod->range_off[PDB_DbiCompUnitRange_Symbols], mod->range_off[PDB_DbiCompUnitRange_Symbols + 1]));
|
||||
for (U64 cursor = 0; cursor < sym_data_size; ) {
|
||||
CV_Symbol symbol = {0};
|
||||
U64 read_size = cv_read_symbol(sym_data, cursor, PDB_SYMBOL_ALIGN, &symbol);
|
||||
T_Ok(read_size > 0);
|
||||
cursor += read_size;
|
||||
T_Ok(symbol.kind == CV_SymKind_LPROC32 || symbol.kind == CV_SymKind_END);
|
||||
}
|
||||
}
|
||||
|
||||
// global symbol stream must have public and references to the static stubs
|
||||
String8 symbol_data = msf_data_from_stream(msf, dbi->sym_sn);
|
||||
for (U64 cursor = 0; cursor < symbol_data.size; ) {
|
||||
CV_Symbol symbol = {0};
|
||||
U64 read_size = cv_read_symbol(symbol_data, cursor, PDB_SYMBOL_ALIGN, &symbol);
|
||||
T_Ok(read_size > 0);
|
||||
cursor += read_size;
|
||||
T_Ok(symbol.kind == CV_SymKind_PUB32 ||
|
||||
symbol.kind == CV_SymKind_LPROCREF);
|
||||
}
|
||||
|
||||
// types must be stripped
|
||||
String8 tpi = msf_data_from_stream(msf, PDB_FixedStream_Tpi);
|
||||
T_Ok(tpi.size == sizeof(PDB_TpiHeader));
|
||||
String8 ipi = msf_data_from_stream(msf, PDB_FixedStream_Ipi);
|
||||
T_Ok(ipi.size == sizeof(PDB_TpiHeader));
|
||||
}
|
||||
|
||||
TEST(patch_cv_symbol_tree)
|
||||
{
|
||||
String8List raw_symbols = {0};
|
||||
|
||||
Reference in New Issue
Block a user