mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-05 21:38:40 +00:00
fix crash on COMDAT folding communal variable
This commit is contained in:
committed by
Ryan Fleury
parent
9060004827
commit
fb0e8d7579
+2
-1
@@ -2661,8 +2661,9 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
|
|||||||
|
|
||||||
if (interp == COFF_SymbolValueInterp_Common) {
|
if (interp == COFF_SymbolValueInterp_Common) {
|
||||||
LNK_Symbol *defn = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, symbol.name);
|
LNK_Symbol *defn = lnk_symbol_table_search(symtab, LNK_SymbolScope_Defined, symbol.name);
|
||||||
|
COFF_ParsedSymbol defn_parsed = lnk_parsed_symbol_from_coff_symbol_idx(defn->u.defined.obj, defn->u.defined.symbol_idx);
|
||||||
if (defn) {
|
if (defn) {
|
||||||
LNK_SectionContrib *sc = sect_map[obj_idx][symbol.section_number-1];
|
LNK_SectionContrib *sc = sect_map[defn->u.defined.obj->input_idx][defn_parsed.section_number-1];
|
||||||
if (obj->header.is_big_obj) {
|
if (obj->header.is_big_obj) {
|
||||||
COFF_Symbol32 *symbol32 = symbol.raw_symbol;
|
COFF_Symbol32 *symbol32 = symbol.raw_symbol;
|
||||||
symbol32->section_number = safe_cast_u32(sc->u.sect_idx + 1);
|
symbol32->section_number = safe_cast_u32(sc->u.sect_idx + 1);
|
||||||
|
|||||||
@@ -11,12 +11,6 @@ lnk_error_obj(LNK_ErrorCode code, LNK_Obj *obj, char *fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
lnk_error_multiply_defined_symbol(LNK_Obj *defn_obj, LNK_Obj *conf_obj, String8 symbol_name)
|
|
||||||
{
|
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, defn_obj, "symbol %S is multiply defined in %S", symbol_name, conf_obj->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
internal LNK_ObjNodeArray
|
internal LNK_ObjNodeArray
|
||||||
|
|||||||
@@ -166,6 +166,12 @@ lnk_symbol_hash_trie_chunk_list_push(Arena *arena, LNK_SymbolHashTrieChunkList *
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
lnk_error_multiply_defined_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||||
|
{
|
||||||
|
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, dst->u.defined.obj, "symbol \"%S\" (No. %#x) is multiply defined in %S (No. %#x)", dst->name, dst->u.defined.symbol_idx, src->u.defined.obj->path, src->u.defined.symbol_idx);
|
||||||
|
}
|
||||||
|
|
||||||
internal B32
|
internal B32
|
||||||
lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
||||||
{
|
{
|
||||||
@@ -196,25 +202,25 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
COFF_SymbolValueInterpType src_interp = coff_interp_symbol(src_parsed.section_number, src_parsed.value, src_parsed.storage_class);
|
COFF_SymbolValueInterpType src_interp = coff_interp_symbol(src_parsed.section_number, src_parsed.value, src_parsed.storage_class);
|
||||||
|
|
||||||
if (dst_interp == COFF_SymbolValueInterp_Regular && src_interp == COFF_SymbolValueInterp_Abs) {
|
if (dst_interp == COFF_SymbolValueInterp_Regular && src_interp == COFF_SymbolValueInterp_Abs) {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, dst->u.defined.obj, "symbol \"%S\" (No. %#x) is multiply defined in %S (No. %#x)", dst->name, dst->u.defined.symbol_idx, src->u.defined.obj->path, src->u.defined.symbol_idx);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
// abs vs regular
|
// abs vs regular
|
||||||
else if ((dst_interp == COFF_SymbolValueInterp_Abs && src_interp == COFF_SymbolValueInterp_Regular) ||
|
else if ((dst_interp == COFF_SymbolValueInterp_Abs && src_interp == COFF_SymbolValueInterp_Regular) ||
|
||||||
(dst_interp == COFF_SymbolValueInterp_Regular && src_interp == COFF_SymbolValueInterp_Abs)) {
|
(dst_interp == COFF_SymbolValueInterp_Regular && src_interp == COFF_SymbolValueInterp_Abs)) {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, dst->u.defined.obj, "symbol \"%S\" (No. %#x) is multiply defined in %S (No. %#x)", dst->name, dst->u.defined.symbol_idx, src->u.defined.obj->path, src->u.defined.symbol_idx);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
// abs vs common
|
// abs vs common
|
||||||
else if (dst_interp == COFF_SymbolValueInterp_Abs && src_interp == COFF_SymbolValueInterp_Common) {
|
else if (dst_interp == COFF_SymbolValueInterp_Abs && src_interp == COFF_SymbolValueInterp_Common) {
|
||||||
if (dst->u.defined.obj->input_idx < src->u.defined.obj->input_idx) {
|
if (dst->u.defined.obj->input_idx < src->u.defined.obj->input_idx) {
|
||||||
can_replace = 1;
|
can_replace = 1;
|
||||||
} else {
|
} else {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, dst->u.defined.obj, "symbol \"%S\" (No. %#x) is multiply defined in %S (No. %#x)", dst->name, dst->u.defined.symbol_idx, src->u.defined.obj->path, src->u.defined.symbol_idx);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// common vs abs
|
// common vs abs
|
||||||
else if (dst_interp == COFF_SymbolValueInterp_Common && src_interp == COFF_SymbolValueInterp_Abs) {
|
else if (dst_interp == COFF_SymbolValueInterp_Common && src_interp == COFF_SymbolValueInterp_Abs) {
|
||||||
if (dst->u.defined.obj->input_idx < src->u.defined.obj->input_idx) {
|
if (dst->u.defined.obj->input_idx < src->u.defined.obj->input_idx) {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, dst->u.defined.obj, "symbol \"%S\" (No. %#x) is multiply defined in %S (No. %#x)", dst->name, dst->u.defined.symbol_idx, src->u.defined.obj->path, src->u.defined.symbol_idx);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// weak vs weak
|
// weak vs weak
|
||||||
@@ -234,41 +240,53 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
}
|
}
|
||||||
// regular,common vs regular,common
|
// regular,common vs regular,common
|
||||||
else if ((dst_interp == COFF_SymbolValueInterp_Regular || dst_interp == COFF_SymbolValueInterp_Common) && (src_interp == COFF_SymbolValueInterp_Regular || src_interp == COFF_SymbolValueInterp_Common)) {
|
else if ((dst_interp == COFF_SymbolValueInterp_Regular || dst_interp == COFF_SymbolValueInterp_Common) && (src_interp == COFF_SymbolValueInterp_Regular || src_interp == COFF_SymbolValueInterp_Common)) {
|
||||||
U32 dst_comdat_symbol_idx = dst_obj->comdats[dst_parsed.section_number-1];
|
B32 is_dst_single_defn = 0;
|
||||||
U32 src_comdat_symbol_idx = src_obj->comdats[src_parsed.section_number-1];
|
B32 is_src_single_defn = 0;
|
||||||
if (dst_comdat_symbol_idx == ~0 || src_comdat_symbol_idx == ~0) {
|
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src_obj, "multiply defined symbol %S in %S", dst->name, dst_obj->path);
|
COFF_ComdatSelectType dst_select;
|
||||||
} else {
|
U32 dst_section_length;
|
||||||
COFF_ComdatSelectType dst_select;
|
U32 dst_check_sum;
|
||||||
U32 dst_section_length;
|
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
||||||
U32 dst_check_sum;
|
U32 dst_comdat_symbol_idx = dst_obj->comdats[dst_parsed.section_number-1];
|
||||||
if (dst_interp == COFF_SymbolValueInterp_Regular) {
|
if (dst_comdat_symbol_idx != max_U32) {
|
||||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(dst_obj, dst_comdat_symbol_idx);
|
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(dst_obj, dst_comdat_symbol_idx);
|
||||||
coff_parse_secdef(secdef, dst_obj->header.is_big_obj, &dst_select, 0, &dst_section_length, &dst_check_sum);
|
coff_parse_secdef(secdef, dst_obj->header.is_big_obj, &dst_select, 0, &dst_section_length, &dst_check_sum);
|
||||||
} else {
|
} else {
|
||||||
dst_select = COFF_ComdatSelect_Largest;
|
is_dst_single_defn = 1;
|
||||||
dst_section_length = dst_parsed.value;
|
|
||||||
dst_check_sum = 0;
|
|
||||||
}
|
}
|
||||||
|
} else if (dst_interp == COFF_SymbolValueInterp_Common) {
|
||||||
|
dst_select = COFF_ComdatSelect_Largest;
|
||||||
|
dst_section_length = dst_parsed.value;
|
||||||
|
dst_check_sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
COFF_ComdatSelectType src_select;
|
COFF_ComdatSelectType src_select;
|
||||||
U32 src_section_length;
|
U32 src_section_length;
|
||||||
U32 src_check_sum;
|
U32 src_check_sum;
|
||||||
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
if (src_interp == COFF_SymbolValueInterp_Regular) {
|
||||||
|
U32 src_comdat_symbol_idx = src_obj->comdats[src_parsed.section_number-1];
|
||||||
|
if (src_comdat_symbol_idx != max_U32) {
|
||||||
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(src_obj, src_comdat_symbol_idx);
|
COFF_ParsedSymbol secdef = lnk_parsed_symbol_from_coff_symbol_idx(src_obj, src_comdat_symbol_idx);
|
||||||
coff_parse_secdef(secdef, src_obj->header.is_big_obj, &src_select, 0, &src_section_length, &src_check_sum);
|
coff_parse_secdef(secdef, src_obj->header.is_big_obj, &src_select, 0, &src_section_length, &src_check_sum);
|
||||||
} else {
|
} else {
|
||||||
src_select = COFF_ComdatSelect_Largest;
|
is_src_single_defn = 1;
|
||||||
src_section_length = src_parsed.value;
|
|
||||||
src_check_sum = 0;
|
|
||||||
}
|
}
|
||||||
|
} else if (src_interp == COFF_SymbolValueInterp_Common) {
|
||||||
|
src_select = COFF_ComdatSelect_Largest;
|
||||||
|
src_section_length = src_parsed.value;
|
||||||
|
src_check_sum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_dst_single_defn || is_src_single_defn) {
|
||||||
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
|
} else {
|
||||||
// handle objs compiled with /GR- and /GR
|
// handle objs compiled with /GR- and /GR
|
||||||
if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest) ||
|
if ((src_select == COFF_ComdatSelect_Any && dst_select == COFF_ComdatSelect_Largest)) {
|
||||||
(src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any)) {
|
|
||||||
dst_select = COFF_ComdatSelect_Largest;
|
|
||||||
src_select = COFF_ComdatSelect_Largest;
|
src_select = COFF_ComdatSelect_Largest;
|
||||||
}
|
}
|
||||||
|
if (src_select == COFF_ComdatSelect_Largest && dst_select == COFF_ComdatSelect_Any) {
|
||||||
|
dst_select = COFF_ComdatSelect_Largest;
|
||||||
|
}
|
||||||
|
|
||||||
if (src_select == dst_select) {
|
if (src_select == dst_select) {
|
||||||
switch (src_select) {
|
switch (src_select) {
|
||||||
@@ -282,13 +300,13 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_ComdatSelect_NoDuplicates: {
|
case COFF_ComdatSelect_NoDuplicates: {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src_obj, "multiply defined symbol %S in %S", dst->name, dst_obj->path);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
} break;
|
} break;
|
||||||
case COFF_ComdatSelect_SameSize: {
|
case COFF_ComdatSelect_SameSize: {
|
||||||
if (dst_section_length == src_section_length) {
|
if (dst_section_length == src_section_length) {
|
||||||
can_replace = src_obj->input_idx < dst_obj->input_idx;
|
can_replace = src_obj->input_idx < dst_obj->input_idx;
|
||||||
} else {
|
} else {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src_obj, "multiply defined symbol %S in %S", dst->name, dst_obj->path);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_ComdatSelect_ExactMatch: {
|
case COFF_ComdatSelect_ExactMatch: {
|
||||||
@@ -308,7 +326,7 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
if (is_exact_match) {
|
if (is_exact_match) {
|
||||||
can_replace = src_obj->input_idx < dst_obj->input_idx;
|
can_replace = src_obj->input_idx < dst_obj->input_idx;
|
||||||
} else {
|
} else {
|
||||||
lnk_error_obj(LNK_Error_MultiplyDefinedSymbol, src_obj, "multiply defined symbol %S in %S", dst->name, dst_obj->path);
|
lnk_error_multiply_defined_symbol(dst, src);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case COFF_ComdatSelect_Largest: {
|
case COFF_ComdatSelect_Largest: {
|
||||||
@@ -334,8 +352,8 @@ lnk_can_replace_symbol(LNK_Symbol *dst, LNK_Symbol *src)
|
|||||||
String8 src_select_str = coff_string_from_comdat_select_type(src_select);
|
String8 src_select_str = coff_string_from_comdat_select_type(src_select);
|
||||||
String8 dst_select_str = coff_string_from_comdat_select_type(dst_select);
|
String8 dst_select_str = coff_string_from_comdat_select_type(dst_select);
|
||||||
lnk_error_obj(LNK_Warning_UnresolvedComdat, src_obj,
|
lnk_error_obj(LNK_Warning_UnresolvedComdat, src_obj,
|
||||||
"%S: COMDAT selection conflict detected, current selection %S, leader selection %S from %S",
|
"%S: COMDAT selection conflict detected, current selection %S, leader selection %S from %S",
|
||||||
src->name, src_select_str, dst_select_str, dst_obj);
|
src->name, src_select_str, dst_select_str, dst_obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user