mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-07 22:38:41 +00:00
make const data eligible for ICF
This commit is contained in:
committed by
Ryan Fleury
parent
c629c5b10e
commit
2d827ac15d
+13
-1
@@ -2977,6 +2977,7 @@ typedef enum LNK_ICF_ColorSpace
|
||||
LNK_ICF_ColorSpace_Code,
|
||||
LNK_ICF_ColorSpace_Unwind,
|
||||
LNK_ICF_ColorSpace_VFTable,
|
||||
LNK_ICF_ColorSpace_ConstData, // string literals, float consts, const tables (/Gw and /GF)
|
||||
LNK_ICF_ColorSpace_COUNT,
|
||||
} LNK_ICF_ColorSpace;
|
||||
|
||||
@@ -2989,6 +2990,7 @@ lnk_string_from_icf_color_space(LNK_ICF_ColorSpace color_space)
|
||||
case LNK_ICF_ColorSpace_Code: { result = str8_lit("Code"); } break;
|
||||
case LNK_ICF_ColorSpace_Unwind: { result = str8_lit("Unwind"); } break;
|
||||
case LNK_ICF_ColorSpace_VFTable: { result = str8_lit("VFTables"); } break;
|
||||
case LNK_ICF_ColorSpace_ConstData: { result = str8_lit("ConstData"); } break;
|
||||
case LNK_ICF_ColorSpace_COUNT: { result = str8_lit("Unknown"); } break;
|
||||
}
|
||||
return result;
|
||||
@@ -3017,13 +3019,23 @@ lnk_icf_color_space_from_section(LNK_Obj *obj, U32 sect_idx)
|
||||
if (str8_match(section_name, str8_lit(".xdata"), 0) || str8_match(section_name, str8_lit(".pdata"), 0)) {
|
||||
result = LNK_ICF_ColorSpace_Unwind;
|
||||
} else {
|
||||
// fold MSVC vftables separately from other read-only data
|
||||
LNK_ObjSymbolRef symlink_ref = {0};
|
||||
if (lnk_obj_get_comdat_symlink(obj, sect_idx + 1, &symlink_ref)) {
|
||||
String8 symlink_name = lnk_symbol_name_from_coff_symbol_idx(symlink_ref.obj, symlink_ref.symbol_idx);
|
||||
// fold MSVC vftables separately from other read-only data
|
||||
if (str8_starts_with(symlink_name, str8_lit(MSCRT_VFTABLE_SYMBOL_PREFIX))) {
|
||||
result = LNK_ICF_ColorSpace_VFTable;
|
||||
}
|
||||
// fold ordinary read-only data COMDATs; do not fold declarations and vtables that require unique addresses
|
||||
else if (!str8_starts_with(symlink_name, str8_lit(MSCRT_VBTABLE_SYMBOL_PREFIX))) {
|
||||
COFF_ComdatSelectType select = COFF_ComdatSelect_Null;
|
||||
if (lnk_try_comdat_props_from_section_number(obj, sect_idx + 1, &select, 0, 0, 0)) {
|
||||
if (select == COFF_ComdatSelect_Any || select == COFF_ComdatSelect_SameSize ||
|
||||
select == COFF_ComdatSelect_ExactMatch || select == COFF_ComdatSelect_Largest) {
|
||||
result = LNK_ICF_ColorSpace_ConstData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9249,7 +9249,7 @@ TEST(icf_readonly_non_vftable_data_policy)
|
||||
{
|
||||
U8 data_bytes[] = { 1, 2, 3, 4 };
|
||||
U8 entry_text[] = { 0xc3 };
|
||||
U8 addresses[2 * sizeof(U64)] = {0};
|
||||
U8 addresses[4 * sizeof(U64)] = {0};
|
||||
|
||||
T_Ok(t_write_def_obj("icf_rdata_policy.obj", (T_COFF_DefObj){
|
||||
.machine = T_COFF_DefSetMachine(X64),
|
||||
@@ -9257,12 +9257,15 @@ TEST(icf_readonly_non_vftable_data_policy)
|
||||
{ "entry", ".text", str8_array_fixed(entry_text), .flags = "rx:code@1" },
|
||||
{ "data_a", ".rdata$mn", str8_array_fixed(data_bytes), .flags = "r:data@1", .raw_flags = COFF_SectionFlag_LnkCOMDAT },
|
||||
{ "data_b", ".rdata$mn", str8_array_fixed(data_bytes), .flags = "r:data@1", .raw_flags = COFF_SectionFlag_LnkCOMDAT },
|
||||
{ "addresses", ".data", str8_array_fixed(addresses), .flags = "rw:data@1", .relocs = (T_COFF_DefReloc[]){ T_COFF_DefReloc(X64_Addr64, 0, "data_a"), T_COFF_DefReloc(X64_Addr64, 8, "data_b"), {0} } },
|
||||
{ "data_c", ".rdata$mn", str8_array_fixed(data_bytes), .flags = "r:data@1", .raw_flags = COFF_SectionFlag_LnkCOMDAT },
|
||||
{ "data_d", ".rdata$mn", str8_array_fixed(data_bytes), .flags = "r:data@1", .raw_flags = COFF_SectionFlag_LnkCOMDAT },
|
||||
{ "addresses", ".data", str8_array_fixed(addresses), .flags = "rw:data@1", .relocs = (T_COFF_DefReloc[]){ T_COFF_DefReloc(X64_Addr64, 0, "data_a"), T_COFF_DefReloc(X64_Addr64, 8, "data_b"), T_COFF_DefReloc(X64_Addr64, 16, "data_c"), T_COFF_DefReloc(X64_Addr64, 24, "data_d"), {0} } },
|
||||
{0}
|
||||
},
|
||||
.symbols = (T_COFF_DefSymbol[]){
|
||||
T_COFF_DefSymbol_Secdef("data_a", COFF_ComdatSelect_NoDuplicates), T_COFF_DefSymbol_Secdef("data_b", COFF_ComdatSelect_NoDuplicates),
|
||||
T_COFF_DefSymbol_ExternFunc("entry", "entry", 0), T_COFF_DefSymbol_Extern("data_a", "data_a", 0), T_COFF_DefSymbol_Extern("data_b", "data_b", 0), T_COFF_DefSymbol_Extern("addresses", "addresses", 0),
|
||||
T_COFF_DefSymbol_Secdef("data_c", COFF_ComdatSelect_Any), T_COFF_DefSymbol_Secdef("data_d", COFF_ComdatSelect_Any),
|
||||
T_COFF_DefSymbol_ExternFunc("entry", "entry", 0), T_COFF_DefSymbol_Extern("data_a", "data_a", 0), T_COFF_DefSymbol_Extern("data_b", "data_b", 0), T_COFF_DefSymbol_Extern("data_c", "data_c", 0), T_COFF_DefSymbol_Extern("data_d", "data_d", 0), T_COFF_DefSymbol_Extern("addresses", "addresses", 0),
|
||||
{0}
|
||||
}
|
||||
}));
|
||||
@@ -9270,11 +9273,13 @@ TEST(icf_readonly_non_vftable_data_policy)
|
||||
t_invoke_linkerf("/subsystem:console /entry:entry /out:a.exe /opt:ref,icf /include:addresses icf_rdata_policy.obj");
|
||||
T_Ok(g_last_exit_code == 0);
|
||||
|
||||
U64 vaddrs[2] = {0};
|
||||
U64 vaddrs[4] = {0};
|
||||
T_Ok(t_read_exe_data_vaddrs(arena, str8_lit("a.exe"), vaddrs, ArrayCount(vaddrs)));
|
||||
T_Ok(vaddrs[0] != 0);
|
||||
T_Ok(vaddrs[1] != 0);
|
||||
T_Ok(vaddrs[0] != vaddrs[1]);
|
||||
T_Ok(vaddrs[2] != 0);
|
||||
T_Ok(vaddrs[2] == vaddrs[3]);
|
||||
}
|
||||
|
||||
TEST(icf_cpp_identical_functions_fold)
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
// MSVC C++ vftable symbols start with this decorated-name prefix.
|
||||
#define MSCRT_VFTABLE_SYMBOL_PREFIX "??_7"
|
||||
#define MSCRT_VBTABLE_SYMBOL_PREFIX "??_8"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@@ -380,4 +381,3 @@ mscrt_catch_blocks_from_data_x8664(Arena *arena,
|
||||
internal String8 mscrt_string_from_eh_adjectives(Arena *arena, MSCRT_EhHandlerTypeFlags adjectives);
|
||||
|
||||
#endif // MSVC_CRT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user