diff --git a/src/linker/lnk_error.h b/src/linker/lnk_error.h index a86b9086..65d0170d 100644 --- a/src/linker/lnk_error.h +++ b/src/linker/lnk_error.h @@ -36,6 +36,7 @@ typedef enum LNK_Error_SectRefsDiscardedMemory, LNK_Error_IllegalSectionMerge, LNK_Error_IllegalRelocation, + LNK_Error_CircularMerge, LNK_Error_StopLast, LNK_Error_First, diff --git a/src/linker/lnk_section_table.c b/src/linker/lnk_section_table.c index ed83c1fa..cb2dee47 100644 --- a/src/linker/lnk_section_table.c +++ b/src/linker/lnk_section_table.c @@ -275,6 +275,19 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l } } } + + // guard against circular merges + { + if (str8_match(merge_node->data.dst, merge_node->data.src, 0)) { + lnk_error(LNK_Error_CircularMerge, "detected circular /MERGE:%S=%S", merge_node->data.src, merge_node->data.dst); + } + for (LNK_SectionNode *sect_n = sectab->merge_list.first; sect_n != 0; sect_n = sect_n->next) { + if (str8_match(sect_n->data.name, merge_node->data.dst, 0) || + str8_match(sect_n->data.name, merge_node->data.src, 0)) { + lnk_error(LNK_Error_CircularMerge, "detected circular /MERGE:%S=%S", merge_node->data.src, merge_node->data.dst); + } + } + } // are we trying to merge section that was already merged? LNK_Section *merge_sect = 0;