mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
use string table extension for long section names
This commit is contained in:
+35
-6
@@ -3892,7 +3892,7 @@ lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U6
|
||||
}
|
||||
|
||||
internal String8List
|
||||
lnk_build_win32_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sects, U64 expected_image_header_size)
|
||||
lnk_build_win32_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sects, U64 expected_image_header_size, U64 *file_header_offset_out, String8List *string_table_out)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
|
||||
@@ -3951,6 +3951,8 @@ lnk_build_win32_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config
|
||||
file_header->section_count = sects.count;
|
||||
file_header->optional_header_size = (has_pe_plus_header ? sizeof(PE_OptionalHeader32Plus) : sizeof(PE_OptionalHeader32)) + (sizeof(PE_DataDirectory) * config->data_dir_count);
|
||||
file_header->flags = config->file_characteristics;
|
||||
|
||||
*file_header_offset_out = result.total_size;
|
||||
str8_list_push(arena, &result, str8_struct(file_header));
|
||||
}
|
||||
|
||||
@@ -4061,13 +4063,21 @@ lnk_build_win32_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config
|
||||
|
||||
if (coff_section->flags & COFF_SectionFlag_LnkRemove) { continue; }
|
||||
|
||||
// TODO: for objs we can store long name in string table and write here /offset
|
||||
String8 section_name = sect->name;
|
||||
|
||||
// use string table extension to store long section names
|
||||
if (sect->name.size > sizeof(coff_section->name)) {
|
||||
lnk_error(LNK_Warning_LongSectionName, "not enough space in COFF section header to store entire name \"%S\"", sect->name);
|
||||
if (string_table_out->node_count == 0) {
|
||||
U32 *string_table_size = push_array(arena, U32, 1);
|
||||
str8_list_push_front(arena, string_table_out, str8_struct(string_table_size));
|
||||
}
|
||||
U64 name_offset = string_table_out->total_size;
|
||||
str8_list_push(arena, string_table_out, push_cstr(arena, sect->name));
|
||||
section_name = push_str8f(arena, "/%u", name_offset);
|
||||
}
|
||||
|
||||
MemorySet(&coff_section->name[0], 0, sizeof(coff_section->name));
|
||||
MemoryCopy(&coff_section->name[0], sect->name.str, Min(sect->name.size, sizeof(coff_section->name)));
|
||||
MemoryCopy(&coff_section->name[0], section_name.str, Min(section_name.size, sizeof(coff_section->name)));
|
||||
coff_section->vsize = sect->vsize;
|
||||
coff_section->voff = sect->voff;
|
||||
coff_section->fsize = sect->fsize;
|
||||
@@ -4108,6 +4118,12 @@ lnk_build_win32_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
// write string table size
|
||||
if (string_table_out->total_size) {
|
||||
U32 *string_table_size = (U32 *)string_table_out->first->string.str;
|
||||
*string_table_size = safe_cast_u32(string_table_out->total_size);
|
||||
}
|
||||
|
||||
Assert(result.total_size == expected_image_header_size);
|
||||
ProfEnd();
|
||||
return result;
|
||||
@@ -4453,8 +4469,10 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
||||
}
|
||||
|
||||
// build win32 image header
|
||||
U64 image_file_header_off = 0;
|
||||
String8List image_string_table = {0};
|
||||
{
|
||||
String8List image_header_data = lnk_build_win32_header(sectab->arena, symtab, config, task.image_sects, AlignPow2(expected_image_header_size, config->file_align));
|
||||
String8List image_header_data = lnk_build_win32_header(sectab->arena, symtab, config, task.image_sects, AlignPow2(expected_image_header_size, config->file_align), &image_file_header_off, &image_string_table);
|
||||
LNK_Section *image_header_sect = lnk_section_table_push(sectab, str8_lit(".rad_linker_image_header_section"), 0);
|
||||
LNK_SectionContribChunk *image_header_sc_chunk = lnk_section_contrib_chunk_list_push_chunk(sectab->arena, &image_header_sect->contribs, 1, str8_zero());
|
||||
LNK_SectionContrib *image_header_sc = lnk_section_contrib_chunk_push(image_header_sc_chunk, 1);
|
||||
@@ -4471,7 +4489,7 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
||||
ProfBegin("Image Fill");
|
||||
|
||||
ProfBeginV("Alloc Image Buffer [%M]", lnk_section_table_total_fsize(sectab));
|
||||
image_data.size = lnk_section_table_total_fsize(sectab);
|
||||
image_data.size = lnk_section_table_total_fsize(sectab) + image_string_table.total_size;
|
||||
image_data.str = push_array_no_zero(arena->v[0], U8, image_data.size);
|
||||
ProfEnd();
|
||||
|
||||
@@ -4522,6 +4540,17 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
||||
task.u.image_fill.fill_nodes = fill_nodes;
|
||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_image_fill_task, &task, "Fill");
|
||||
|
||||
if (image_string_table.total_size) {
|
||||
ProfBegin("Copy String Table");
|
||||
String8 buffer = str8_list_join(scratch.arena, &image_string_table, 0);
|
||||
MemoryCopy(image_data.str + (image_data.size - buffer.size), buffer.str, buffer.size);
|
||||
ProfEnd();
|
||||
|
||||
// patch string table offset
|
||||
COFF_FileHeader *file_header = (COFF_FileHeader *)(image_data.str + image_file_header_off);
|
||||
file_header->symbol_table_foff = safe_cast_u32(image_data.size - buffer.size);
|
||||
}
|
||||
|
||||
temp_end(temp);
|
||||
|
||||
ProfEnd();
|
||||
|
||||
+1
-1
@@ -378,7 +378,7 @@ internal void lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *c
|
||||
|
||||
internal String8List lnk_build_guard_tables(TP_Context *tp, LNK_SectionTable *sectab, LNK_SymbolTable *symtab, U64 objs_count, LNK_Obj **objs, COFF_MachineType machine, String8 entry_point_name, LNK_GuardFlags guard_flags, B32 emit_suppress_flag);
|
||||
internal String8 lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_temp, LNK_Config *config, U64 objs_count, LNK_Obj **objs);
|
||||
internal String8List lnk_build_win32_image_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sect_arr, U64 expected_image_header_size);
|
||||
internal String8List lnk_build_win32_image_header(Arena *arena, LNK_SymbolTable *symtab, LNK_Config *config, LNK_SectionArray sect_arr, U64 expected_image_header_size, U64 *file_header_offset_out, String8List *string_table_out);
|
||||
internal LNK_ImageContext lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolTable *symtab, U64 obj_count, LNK_Obj **objs);
|
||||
|
||||
// --- Logger ------------------------------------------------------------------
|
||||
|
||||
@@ -3909,6 +3909,38 @@ T_BeginTest(fail_if_mismatch)
|
||||
}
|
||||
T_EndTest;
|
||||
|
||||
T_BeginTest(long_section_name)
|
||||
{
|
||||
Arch arch = Arch_x64;
|
||||
|
||||
COFF_ObjWriter *cow = coff_obj_writer_alloc(0, COFF_MachineType_X64);
|
||||
U8 text[] = { 0xc3 };
|
||||
COFF_ObjSection *text_sect = coff_obj_writer_push_section(cow, str8_lit(".text"), PE_TEXT_SECTION_FLAGS, str8_array_fixed(text));
|
||||
coff_obj_writer_push_section(cow, str8_lit(".debug_info"), PE_DATA_SECTION_FLAGS, str8_lit("DEBUG_INFO"));
|
||||
coff_obj_writer_push_section(cow, str8_lit(".debug_abbrev"), PE_DATA_SECTION_FLAGS, str8_lit("DEBUG_ABBREV"));
|
||||
coff_obj_writer_push_symbol_extern(cow, str8_lit("entry"), 0, text_sect);
|
||||
String8 raw_coff = coff_obj_writer_serialize(scratch.arena, cow);
|
||||
coff_obj_writer_release(&cow);
|
||||
|
||||
// link test.obj
|
||||
T_Ok(t_write_file(str8_lit("test.obj"), raw_coff));
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe test.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
|
||||
// load linked exe
|
||||
String8 exe = t_read_file(scratch.arena, str8_lit("a.exe"));
|
||||
PE_BinInfo pe = pe_bin_info_from_data(scratch.arena, exe);
|
||||
COFF_SectionHeader *section_table = (COFF_SectionHeader *)str8_substr(exe, pe.section_table_range).str;
|
||||
String8 string_table = str8_substr(exe, pe.string_table_range);
|
||||
|
||||
COFF_SectionHeader *debug_info = coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".debug_info"));
|
||||
T_Ok(debug_info);
|
||||
|
||||
COFF_SectionHeader *debug_abbrev = coff_section_header_from_name(string_table, section_table, pe.section_count, str8_lit(".debug_abbrev"));
|
||||
T_Ok(debug_abbrev);
|
||||
}
|
||||
T_EndTest;
|
||||
|
||||
#if 0
|
||||
|
||||
T_BeginTest(fold_two_funcs)
|
||||
|
||||
Reference in New Issue
Block a user